diff options
173 files changed, 4683 insertions, 3031 deletions
@@ -272,7 +272,7 @@ fwbase_dirs_to_document := \ # as "final" in the official SDK APIs. fwbase_dirs_to_document += core/config/sdk -# These are relative to dalvik/libcore +# These are relative to libcore # Intentionally not included from libcore: # icu openssl suncompat support libcore_to_document := \ @@ -312,7 +312,7 @@ non_base_dirs := \ dirs_to_document := \ $(fwbase_dirs_to_document) \ $(non_base_dirs) \ - $(addprefix ../../dalvik/libcore/, $(libcore_to_document)) + $(addprefix ../../libcore/, $(libcore_to_document)) html_dirs := \ $(FRAMEWORKS_BASE_SUBDIRS) \ diff --git a/api/current.xml b/api/current.xml index 83d2bc7..d02c826 100644 --- a/api/current.xml +++ b/api/current.xml @@ -127479,6 +127479,17 @@ visibility="public" > </field> +<field name="NETWORK_TYPE_EVDO_B" + type="int" + transient="false" + volatile="false" + value="12" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="NETWORK_TYPE_GPRS" type="int" transient="false" @@ -153221,6 +153232,28 @@ visibility="public" > </field> +<field name="KEYCODE_PAGE_DOWN" + type="int" + transient="false" + volatile="false" + value="93" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="KEYCODE_PAGE_UP" + type="int" + transient="false" + volatile="false" + value="92" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="KEYCODE_PERIOD" type="int" transient="false" @@ -153232,6 +153265,17 @@ visibility="public" > </field> +<field name="KEYCODE_PICTSYMBOLS" + type="int" + transient="false" + volatile="false" + value="94" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="KEYCODE_PLUS" type="int" transient="false" @@ -153408,6 +153452,17 @@ visibility="public" > </field> +<field name="KEYCODE_SWITCH_CHARSET" + type="int" + transient="false" + volatile="false" + value="95" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="KEYCODE_SYM" type="int" transient="false" @@ -197185,7 +197240,7 @@ deprecated="not deprecated" visibility="public" > -<parameter name="t" type="T"> +<parameter name="arg0" type="T"> </parameter> </method> </interface> diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index eca5af9..13e6d5c 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -88,6 +88,8 @@ public class Am { if (op.equals("start")) { runStart(); + } else if (op.equals("startservice")) { + runStartService(); } else if (op.equals("instrument")) { runInstrument(); } else if (op.equals("broadcast")) { @@ -179,6 +181,15 @@ public class Am { return intent; } + private void runStartService() throws Exception { + Intent intent = makeIntent(); + System.out.println("Starting service: " + intent); + ComponentName cn = mAm.startService(null, intent, intent.getType()); + if (cn == null) { + System.err.println("Error: Not found; no service started."); + } + } + private void runStart() throws Exception { Intent intent = makeIntent(); System.out.println("Starting: " + intent); @@ -492,6 +503,8 @@ public class Am { " start an Activity: am start [-D] <INTENT>\n" + " -D: enable debugging\n" + "\n" + + " start a Service: am startservice <INTENT>\n" + + "\n" + " send a broadcast Intent: am broadcast <INTENT>\n" + "\n" + " start an Instrumentation: am instrument [flags] <COMPONENT>\n" + diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java index 79178f4..6539156 100644 --- a/core/java/android/database/Cursor.java +++ b/core/java/android/database/Cursor.java @@ -25,6 +25,9 @@ import java.util.Map; /** * This interface provides random read-write access to the result set returned * by a database query. + * + * Cursor implementations are not required to be synchronized so code using a Cursor from multiple + * threads should perform its own synchronization when using the Cursor. */ public interface Cursor { /** diff --git a/core/java/android/database/CursorToBulkCursorAdaptor.java b/core/java/android/database/CursorToBulkCursorAdaptor.java index 19ad946..05f8014 100644 --- a/core/java/android/database/CursorToBulkCursorAdaptor.java +++ b/core/java/android/database/CursorToBulkCursorAdaptor.java @@ -143,8 +143,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative public void close() { maybeUnregisterObserverProxy(); - mCursor.deactivate(); - + mCursor.close(); } public int requery(IContentObserver observer, CursorWindow window) { diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java index 70b9b83..1c1dacd 100644 --- a/core/java/android/database/sqlite/SQLiteCursor.java +++ b/core/java/android/database/sqlite/SQLiteCursor.java @@ -36,6 +36,9 @@ import java.util.concurrent.locks.ReentrantLock; /** * A Cursor implementation that exposes results from a query on a * {@link SQLiteDatabase}. + * + * SQLiteCursor is not internally synchronized so code using a SQLiteCursor from multiple + * threads should perform its own synchronization when using the SQLiteCursor. */ public class SQLiteCursor extends AbstractWindowedCursor { static final String TAG = "Cursor"; diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index 9ebf5d9..342c0f5 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -1019,7 +1019,8 @@ public class SQLiteDatabase extends SQLiteClosable { * * @param sql The raw SQL statement, may contain ? for unknown values to be * bound later. - * @return a pre-compiled statement object. + * @return A pre-compiled {@link SQLiteStatement} object. Note that + * {@link SQLiteStatement}s are not synchronized, see the documentation for more details. */ public SQLiteStatement compileStatement(String sql) throws SQLException { lock(); @@ -1057,7 +1058,8 @@ public class SQLiteDatabase extends SQLiteClosable { * default sort order, which may be unordered. * @param limit Limits the number of rows returned by the query, * formatted as LIMIT clause. Passing null denotes no LIMIT clause. - * @return A Cursor object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */ public Cursor query(boolean distinct, String table, String[] columns, @@ -1095,7 +1097,8 @@ public class SQLiteDatabase extends SQLiteClosable { * default sort order, which may be unordered. * @param limit Limits the number of rows returned by the query, * formatted as LIMIT clause. Passing null denotes no LIMIT clause. - * @return A Cursor object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */ public Cursor queryWithFactory(CursorFactory cursorFactory, @@ -1133,7 +1136,8 @@ public class SQLiteDatabase extends SQLiteClosable { * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause * (excluding the ORDER BY itself). Passing null will use the * default sort order, which may be unordered. - * @return A {@link Cursor} object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */ public Cursor query(String table, String[] columns, String selection, @@ -1170,7 +1174,8 @@ public class SQLiteDatabase extends SQLiteClosable { * default sort order, which may be unordered. * @param limit Limits the number of rows returned by the query, * formatted as LIMIT clause. Passing null denotes no LIMIT clause. - * @return A {@link Cursor} object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */ public Cursor query(String table, String[] columns, String selection, @@ -1188,7 +1193,8 @@ public class SQLiteDatabase extends SQLiteClosable { * @param selectionArgs You may include ?s in where clause in the query, * which will be replaced by the values from selectionArgs. The * values will be bound as Strings. - * @return A {@link Cursor} object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. */ public Cursor rawQuery(String sql, String[] selectionArgs) { return rawQueryWithFactory(null, sql, selectionArgs, null); @@ -1203,7 +1209,8 @@ public class SQLiteDatabase extends SQLiteClosable { * which will be replaced by the values from selectionArgs. The * values will be bound as Strings. * @param editTable the name of the first table, which is editable - * @return A {@link Cursor} object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. */ public Cursor rawQueryWithFactory( CursorFactory cursorFactory, String sql, String[] selectionArgs, @@ -1255,7 +1262,8 @@ public class SQLiteDatabase extends SQLiteClosable { * values will be bound as Strings. * @param initialRead set the initial count of items to read from the cursor * @param maxRead set the count of items to read on each iteration after the first - * @return A {@link Cursor} object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. * * This work is incomplete and not fully tested or reviewed, so currently * hidden. diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java index 9e85452..d6aa9e6 100644 --- a/core/java/android/database/sqlite/SQLiteProgram.java +++ b/core/java/android/database/sqlite/SQLiteProgram.java @@ -20,6 +20,9 @@ import android.util.Log; /** * A base class for compiled SQLite programs. + * + * SQLiteProgram is not internally synchronized so code using a SQLiteProgram from multiple + * threads should perform its own synchronization when using the SQLiteProgram. */ public abstract class SQLiteProgram extends SQLiteClosable { private static final String TAG = "SQLiteProgram"; diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java index cdd9f86..66f7e6d 100644 --- a/core/java/android/database/sqlite/SQLiteQuery.java +++ b/core/java/android/database/sqlite/SQLiteQuery.java @@ -23,6 +23,9 @@ import android.util.Log; /** * A SQLite program that represents a query that reads the resulting rows into a CursorWindow. * This class is used by SQLiteCursor and isn't useful itself. + * + * SQLiteQuery is not internally synchronized so code using a SQLiteQuery from multiple + * threads should perform its own synchronization when using the SQLiteQuery. */ public class SQLiteQuery extends SQLiteProgram { private static final String TAG = "Cursor"; diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java index 5889ad9..46eae65 100644 --- a/core/java/android/database/sqlite/SQLiteStatement.java +++ b/core/java/android/database/sqlite/SQLiteStatement.java @@ -24,6 +24,9 @@ import android.util.Log; * The statement cannot return multiple rows, but 1x1 result sets are allowed. * Don't use SQLiteStatement constructor directly, please use * {@link SQLiteDatabase#compileStatement(String)} + * + * SQLiteStatement is not internally synchronized so code using a SQLiteStatement from multiple + * threads should perform its own synchronization when using the SQLiteStatement. */ public class SQLiteStatement extends SQLiteProgram { diff --git a/core/java/android/hardware/GeomagneticField.java b/core/java/android/hardware/GeomagneticField.java index b4c04b1..96fbe77 100644 --- a/core/java/android/hardware/GeomagneticField.java +++ b/core/java/android/hardware/GeomagneticField.java @@ -26,8 +26,9 @@ import java.util.GregorianCalendar; * <p>This uses the World Magnetic Model produced by the United States National * Geospatial-Intelligence Agency. More details about the model can be found at * <a href="http://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml">http://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml</a>. - * This class currently uses WMM-2005 which is valid until 2010, but should - * produce acceptable results for several years after that. + * This class currently uses WMM-2010 which is valid until 2015, but should + * produce acceptable results for several years after that. Future versions of + * Android may use a newer version of the model. */ public class GeomagneticField { // The magnetic field at a given point, in nonoteslas in geodetic @@ -43,75 +44,73 @@ public class GeomagneticField { // Constants from WGS84 (the coordinate system used by GPS) static private final float EARTH_SEMI_MAJOR_AXIS_KM = 6378.137f; - static private final float EARTH_SEMI_MINOR_AXIS_KM = 6356.7523f; + static private final float EARTH_SEMI_MINOR_AXIS_KM = 6356.7523142f; static private final float EARTH_REFERENCE_RADIUS_KM = 6371.2f; // These coefficients and the formulae used below are from: - // NOAA Technical Report: The US/UK World Magnetic Model for 2005-2010 + // NOAA Technical Report: The US/UK World Magnetic Model for 2010-2015 static private final float[][] G_COEFF = new float[][] { - { 0f }, - { -29556.8f, -1671.7f }, - { -2340.6f, 3046.9f, 1657.0f }, - { 1335.4f, -2305.1f, 1246.7f, 674.0f }, - { 919.8f, 798.1f, 211.3f, -379.4f, 100.0f }, - { -227.4f, 354.6f, 208.7f, -136.5f, -168.3f, -14.1f }, - { 73.2f, 69.7f, 76.7f, -151.2f, -14.9f, 14.6f, -86.3f }, - { 80.1f, -74.5f, -1.4f, 38.5f, 12.4f, 9.5f, 5.7f, 1.8f }, - { 24.9f, 7.7f, -11.6f, -6.9f, -18.2f, 10.0f, 9.2f, -11.6f, -5.2f }, - { 5.6f, 9.9f, 3.5f, -7.0f, 5.1f, -10.8f, -1.3f, 8.8f, -6.7f, -9.1f }, - { -2.3f, -6.3f, 1.6f, -2.6f, 0.0f, 3.1f, 0.4f, 2.1f, 3.9f, -0.1f, -2.3f }, - { 2.8f, -1.6f, -1.7f, 1.7f, -0.1f, 0.1f, -0.7f, 0.7f, 1.8f, 0.0f, 1.1f, 4.1f }, - { -2.4f, -0.4f, 0.2f, 0.8f, -0.3f, 1.1f, -0.5f, 0.4f, -0.3f, -0.3f, -0.1f, - -0.3f, -0.1f } }; + { 0.0f }, + { -29496.6f, -1586.3f }, + { -2396.6f, 3026.1f, 1668.6f }, + { 1340.1f, -2326.2f, 1231.9f, 634.0f }, + { 912.6f, 808.9f, 166.7f, -357.1f, 89.4f }, + { -230.9f, 357.2f, 200.3f, -141.1f, -163.0f, -7.8f }, + { 72.8f, 68.6f, 76.0f, -141.4f, -22.8f, 13.2f, -77.9f }, + { 80.5f, -75.1f, -4.7f, 45.3f, 13.9f, 10.4f, 1.7f, 4.9f }, + { 24.4f, 8.1f, -14.5f, -5.6f, -19.3f, 11.5f, 10.9f, -14.1f, -3.7f }, + { 5.4f, 9.4f, 3.4f, -5.2f, 3.1f, -12.4f, -0.7f, 8.4f, -8.5f, -10.1f }, + { -2.0f, -6.3f, 0.9f, -1.1f, -0.2f, 2.5f, -0.3f, 2.2f, 3.1f, -1.0f, -2.8f }, + { 3.0f, -1.5f, -2.1f, 1.7f, -0.5f, 0.5f, -0.8f, 0.4f, 1.8f, 0.1f, 0.7f, 3.8f }, + { -2.2f, -0.2f, 0.3f, 1.0f, -0.6f, 0.9f, -0.1f, 0.5f, -0.4f, -0.4f, 0.2f, -0.8f, 0.0f } }; static private final float[][] H_COEFF = new float[][] { - { 0f }, - { 0.0f, 5079.8f }, - { 0.0f, -2594.7f, -516.7f }, - { 0.0f, -199.9f, 269.3f, -524.2f }, - { 0.0f, 281.5f, -226.0f, 145.8f, -304.7f }, - { 0.0f, 42.4f, 179.8f, -123.0f, -19.5f, 103.6f }, - { 0.0f, -20.3f, 54.7f, 63.6f, -63.4f, -0.1f, 50.4f }, - { 0.0f, -61.5f, -22.4f, 7.2f, 25.4f, 11.0f, -26.4f, -5.1f }, - { 0.0f, 11.2f, -21.0f, 9.6f, -19.8f, 16.1f, 7.7f, -12.9f, -0.2f }, - { 0.0f, -20.1f, 12.9f, 12.6f, -6.7f, -8.1f, 8.0f, 2.9f, -7.9f, 6.0f }, - { 0.0f, 2.4f, 0.2f, 4.4f, 4.8f, -6.5f, -1.1f, -3.4f, -0.8f, -2.3f, -7.9f }, - { 0.0f, 0.3f, 1.2f, -0.8f, -2.5f, 0.9f, -0.6f, -2.7f, -0.9f, -1.3f, -2.0f, -1.2f }, - { 0.0f, -0.4f, 0.3f, 2.4f, -2.6f, 0.6f, 0.3f, 0.0f, 0.0f, 0.3f, -0.9f, -0.4f, - 0.8f } }; + { 0.0f }, + { 0.0f, 4944.4f }, + { 0.0f, -2707.7f, -576.1f }, + { 0.0f, -160.2f, 251.9f, -536.6f }, + { 0.0f, 286.4f, -211.2f, 164.3f, -309.1f }, + { 0.0f, 44.6f, 188.9f, -118.2f, 0.0f, 100.9f }, + { 0.0f, -20.8f, 44.1f, 61.5f, -66.3f, 3.1f, 55.0f }, + { 0.0f, -57.9f, -21.1f, 6.5f, 24.9f, 7.0f, -27.7f, -3.3f }, + { 0.0f, 11.0f, -20.0f, 11.9f, -17.4f, 16.7f, 7.0f, -10.8f, 1.7f }, + { 0.0f, -20.5f, 11.5f, 12.8f, -7.2f, -7.4f, 8.0f, 2.1f, -6.1f, 7.0f }, + { 0.0f, 2.8f, -0.1f, 4.7f, 4.4f, -7.2f, -1.0f, -3.9f, -2.0f, -2.0f, -8.3f }, + { 0.0f, 0.2f, 1.7f, -0.6f, -1.8f, 0.9f, -0.4f, -2.5f, -1.3f, -2.1f, -1.9f, -1.8f }, + { 0.0f, -0.9f, 0.3f, 2.1f, -2.5f, 0.5f, 0.6f, 0.0f, 0.1f, 0.3f, -0.9f, -0.2f, 0.9f } }; static private final float[][] DELTA_G = new float[][] { - { 0f }, - { 8.0f, 10.6f }, - { -15.1f, -7.8f, -0.8f }, - { 0.4f, -2.6f, -1.2f, -6.5f }, - { -2.5f, 2.8f, -7.0f, 6.2f, -3.8f }, - { -2.8f, 0.7f, -3.2f, -1.1f, 0.1f, -0.8f }, - { -0.7f, 0.4f, -0.3f, 2.3f, -2.1f, -0.6f, 1.4f }, - { 0.2f, -0.1f, -0.3f, 1.1f, 0.6f, 0.5f, -0.4f, 0.6f }, - { 0.1f, 0.3f, -0.4f, 0.3f, -0.3f, 0.2f, 0.4f, -0.7f, 0.4f }, - { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }; + { 0.0f }, + { 11.6f, 16.5f }, + { -12.1f, -4.4f, 1.9f }, + { 0.4f, -4.1f, -2.9f, -7.7f }, + { -1.8f, 2.3f, -8.7f, 4.6f, -2.1f }, + { -1.0f, 0.6f, -1.8f, -1.0f, 0.9f, 1.0f }, + { -0.2f, -0.2f, -0.1f, 2.0f, -1.7f, -0.3f, 1.7f }, + { 0.1f, -0.1f, -0.6f, 1.3f, 0.4f, 0.3f, -0.7f, 0.6f }, + { -0.1f, 0.1f, -0.6f, 0.2f, -0.2f, 0.3f, 0.3f, -0.6f, 0.2f }, + { 0.0f, -0.1f, 0.0f, 0.3f, -0.4f, -0.3f, 0.1f, -0.1f, -0.4f, -0.2f }, + { 0.0f, 0.0f, -0.1f, 0.2f, 0.0f, -0.1f, -0.2f, 0.0f, -0.1f, -0.2f, -0.2f }, + { 0.0f, 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.1f, 0.0f }, + { 0.0f, 0.0f, 0.1f, 0.1f, -0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.1f, 0.1f } }; static private final float[][] DELTA_H = new float[][] { - { 0f }, - { 0.0f, -20.9f }, - { 0.0f, -23.2f, -14.6f }, - { 0.0f, 5.0f, -7.0f, -0.6f }, - { 0.0f, 2.2f, 1.6f, 5.8f, 0.1f }, - { 0.0f, 0.0f, 1.7f, 2.1f, 4.8f, -1.1f }, - { 0.0f, -0.6f, -1.9f, -0.4f, -0.5f, -0.3f, 0.7f }, - { 0.0f, 0.6f, 0.4f, 0.2f, 0.3f, -0.8f, -0.2f, 0.1f }, - { 0.0f, -0.2f, 0.1f, 0.3f, 0.4f, 0.1f, -0.2f, 0.4f, 0.4f }, - { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }; + { 0.0f }, + { 0.0f, -25.9f }, + { 0.0f, -22.5f, -11.8f }, + { 0.0f, 7.3f, -3.9f, -2.6f }, + { 0.0f, 1.1f, 2.7f, 3.9f, -0.8f }, + { 0.0f, 0.4f, 1.8f, 1.2f, 4.0f, -0.6f }, + { 0.0f, -0.2f, -2.1f, -0.4f, -0.6f, 0.5f, 0.9f }, + { 0.0f, 0.7f, 0.3f, -0.1f, -0.1f, -0.8f, -0.3f, 0.3f }, + { 0.0f, -0.1f, 0.2f, 0.4f, 0.4f, 0.1f, -0.1f, 0.4f, 0.3f }, + { 0.0f, 0.0f, -0.2f, 0.0f, -0.1f, 0.1f, 0.0f, -0.2f, 0.3f, 0.2f }, + { 0.0f, 0.1f, -0.1f, 0.0f, -0.1f, -0.1f, 0.0f, -0.1f, -0.2f, 0.0f, -0.1f }, + { 0.0f, 0.0f, 0.1f, 0.0f, 0.1f, 0.0f, 0.1f, 0.0f, -0.1f, -0.1f, 0.0f, -0.1f }, + { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }; static private final long BASE_TIME = - new GregorianCalendar(2005, 1, 1).getTimeInMillis(); + new GregorianCalendar(2010, 1, 1).getTimeInMillis(); // The ratio between the Gauss-normalized associated Legendre functions and // the Schmid quasi-normalized ones. Compute these once staticly since they @@ -191,7 +190,7 @@ public class GeomagneticField { // We now compute the magnetic field strength given the geocentric // location. The magnetic field is the derivative of the potential // function defined by the model. See NOAA Technical Report: The US/UK - // World Magnetic Model for 2005-2010 for the derivation. + // World Magnetic Model for 2010-2015 for the derivation. float gcX = 0.0f; // Geocentric northwards component. float gcY = 0.0f; // Geocentric eastwards component. float gcZ = 0.0f; // Geocentric downwards component. @@ -406,4 +405,4 @@ public class GeomagneticField { } return schmidtQuasiNorm; } -}
\ No newline at end of file +} diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java index 6cf90d6..7ee35c0 100644 --- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java @@ -31,9 +31,10 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub private static final int DO_UPDATE_CURSOR = 95; private static final int DO_APP_PRIVATE_COMMAND = 100; private static final int DO_TOGGLE_SOFT_INPUT = 105; - - final HandlerCaller mCaller; - final InputMethodSession mInputMethodSession; + private static final int DO_FINISH_SESSION = 110; + + HandlerCaller mCaller; + InputMethodSession mInputMethodSession; // NOTE: we should have a cache of these. static class InputMethodEventCallbackWrapper implements InputMethodSession.EventCallback { @@ -111,6 +112,10 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub mInputMethodSession.toggleSoftInput(msg.arg1, msg.arg2); return; } + case DO_FINISH_SESSION: { + mInputMethodSession = null; + return; + } } Log.w(TAG, "Unhandled message code: " + msg.what); } @@ -158,4 +163,8 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub public void toggleSoftInput(int showFlags, int hideFlags) { mCaller.executeOrSendMessage(mCaller.obtainMessageII(DO_TOGGLE_SOFT_INPUT, showFlags, hideFlags)); } + + public void finishSession() { + mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_SESSION)); + } } diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java index 20a05a5..74ce71a 100644 --- a/core/java/android/inputmethodservice/IInputMethodWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java @@ -23,6 +23,7 @@ import android.view.inputmethod.InputMethodSession; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.lang.ref.WeakReference; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -48,9 +49,9 @@ class IInputMethodWrapper extends IInputMethod.Stub private static final int DO_SHOW_SOFT_INPUT = 60; private static final int DO_HIDE_SOFT_INPUT = 70; - final AbstractInputMethodService mTarget; + final WeakReference<AbstractInputMethodService> mTarget; final HandlerCaller mCaller; - final InputMethod mInputMethod; + final WeakReference<InputMethod> mInputMethod; static class Notifier { boolean notified; @@ -80,21 +81,32 @@ class IInputMethodWrapper extends IInputMethod.Stub public IInputMethodWrapper(AbstractInputMethodService context, InputMethod inputMethod) { - mTarget = context; - mCaller = new HandlerCaller(context, this); - mInputMethod = inputMethod; + mTarget = new WeakReference<AbstractInputMethodService>(context); + mCaller = new HandlerCaller(context.getApplicationContext(), this); + mInputMethod = new WeakReference<InputMethod>(inputMethod); } public InputMethod getInternalInputMethod() { - return mInputMethod; + return mInputMethod.get(); } public void executeMessage(Message msg) { + InputMethod inputMethod = mInputMethod.get(); + // Need a valid reference to the inputMethod for everything except a dump. + if (inputMethod == null && msg.what != DO_DUMP) { + Log.w(TAG, "Input method reference was null, ignoring message: " + msg.what); + return; + } + switch (msg.what) { case DO_DUMP: { + AbstractInputMethodService target = mTarget.get(); + if (target == null) { + return; + } HandlerCaller.SomeArgs args = (HandlerCaller.SomeArgs)msg.obj; try { - mTarget.dump((FileDescriptor)args.arg1, + target.dump((FileDescriptor)args.arg1, (PrintWriter)args.arg2, (String[])args.arg3); } catch (RuntimeException e) { ((PrintWriter)args.arg2).println("Exception: " + e); @@ -106,22 +118,22 @@ class IInputMethodWrapper extends IInputMethod.Stub } case DO_ATTACH_TOKEN: { - mInputMethod.attachToken((IBinder)msg.obj); + inputMethod.attachToken((IBinder)msg.obj); return; } case DO_SET_INPUT_CONTEXT: { - mInputMethod.bindInput((InputBinding)msg.obj); + inputMethod.bindInput((InputBinding)msg.obj); return; } case DO_UNSET_INPUT_CONTEXT: - mInputMethod.unbindInput(); + inputMethod.unbindInput(); return; case DO_START_INPUT: { HandlerCaller.SomeArgs args = (HandlerCaller.SomeArgs)msg.obj; IInputContext inputContext = (IInputContext)args.arg1; InputConnection ic = inputContext != null ? new InputConnectionWrapper(inputContext) : null; - mInputMethod.startInput(ic, (EditorInfo)args.arg2); + inputMethod.startInput(ic, (EditorInfo)args.arg2); return; } case DO_RESTART_INPUT: { @@ -129,33 +141,37 @@ class IInputMethodWrapper extends IInputMethod.Stub IInputContext inputContext = (IInputContext)args.arg1; InputConnection ic = inputContext != null ? new InputConnectionWrapper(inputContext) : null; - mInputMethod.restartInput(ic, (EditorInfo)args.arg2); + inputMethod.restartInput(ic, (EditorInfo)args.arg2); return; } case DO_CREATE_SESSION: { - mInputMethod.createSession(new InputMethodSessionCallbackWrapper( + inputMethod.createSession(new InputMethodSessionCallbackWrapper( mCaller.mContext, (IInputMethodCallback)msg.obj)); return; } case DO_SET_SESSION_ENABLED: - mInputMethod.setSessionEnabled((InputMethodSession)msg.obj, + inputMethod.setSessionEnabled((InputMethodSession)msg.obj, msg.arg1 != 0); return; case DO_REVOKE_SESSION: - mInputMethod.revokeSession((InputMethodSession)msg.obj); + inputMethod.revokeSession((InputMethodSession)msg.obj); return; case DO_SHOW_SOFT_INPUT: - mInputMethod.showSoftInput(msg.arg1, (ResultReceiver)msg.obj); + inputMethod.showSoftInput(msg.arg1, (ResultReceiver)msg.obj); return; case DO_HIDE_SOFT_INPUT: - mInputMethod.hideSoftInput(msg.arg1, (ResultReceiver)msg.obj); + inputMethod.hideSoftInput(msg.arg1, (ResultReceiver)msg.obj); return; } Log.w(TAG, "Unhandled message code: " + msg.what); } @Override protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { - if (mTarget.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) + AbstractInputMethodService target = mTarget.get(); + if (target == null) { + return; + } + if (target.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { fout.println("Permission Denial: can't dump InputMethodManager from from pid=" diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 5499bba..f4fbaad 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1981,15 +1981,19 @@ public class InputMethodService extends AbstractInputMethodService { ei.inputType != InputType.TYPE_NULL); if (hasAction) { mExtractAccessories.setVisibility(View.VISIBLE); - if (ei.actionLabel != null) { - mExtractAction.setText(ei.actionLabel); - } else { - mExtractAction.setText(getTextForImeAction(ei.imeOptions)); + if (mExtractAction != null) { + if (ei.actionLabel != null) { + mExtractAction.setText(ei.actionLabel); + } else { + mExtractAction.setText(getTextForImeAction(ei.imeOptions)); + } + mExtractAction.setOnClickListener(mActionClickListener); } - mExtractAction.setOnClickListener(mActionClickListener); } else { mExtractAccessories.setVisibility(View.GONE); - mExtractAction.setOnClickListener(null); + if (mExtractAction != null) { + mExtractAction.setOnClickListener(null); + } } } diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java index 538e51a..8113aaa 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -304,6 +304,9 @@ public class MobileDataStateTracker extends NetworkStateTracker { case TelephonyManager.NETWORK_TYPE_EVDO_A: networkTypeStr = "evdo"; break; + case TelephonyManager.NETWORK_TYPE_EVDO_B: + networkTypeStr = "evdo"; + break; } return "net.tcp.buffersize." + networkTypeStr; } diff --git a/core/java/android/text/method/PasswordTransformationMethod.java b/core/java/android/text/method/PasswordTransformationMethod.java index fad4f64..b769b76 100644 --- a/core/java/android/text/method/PasswordTransformationMethod.java +++ b/core/java/android/text/method/PasswordTransformationMethod.java @@ -51,6 +51,8 @@ implements TransformationMethod, TextWatcher sp.removeSpan(vr[i]); } + removeVisibleSpans(sp); + sp.setSpan(new ViewReference(view), 0, 0, Spannable.SPAN_POINT_POINT); } @@ -100,10 +102,7 @@ implements TransformationMethod, TextWatcher int pref = TextKeyListener.getInstance().getPrefs(v.getContext()); if ((pref & TextKeyListener.SHOW_PASSWORD) != 0) { if (count > 0) { - Visible[] old = sp.getSpans(0, sp.length(), Visible.class); - for (int i = 0; i < old.length; i++) { - sp.removeSpan(old[i]); - } + removeVisibleSpans(sp); if (count == 1) { sp.setSpan(new Visible(sp, this), start, start + count, @@ -125,14 +124,18 @@ implements TransformationMethod, TextWatcher if (sourceText instanceof Spannable) { Spannable sp = (Spannable) sourceText; - Visible[] old = sp.getSpans(0, sp.length(), Visible.class); - for (int i = 0; i < old.length; i++) { - sp.removeSpan(old[i]); - } + removeVisibleSpans(sp); } } } + private static void removeVisibleSpans(Spannable sp) { + Visible[] old = sp.getSpans(0, sp.length(), Visible.class); + for (int i = 0; i < old.length; i++) { + sp.removeSpan(old[i]); + } + } + private static class PasswordCharSequence implements CharSequence, GetChars { diff --git a/core/java/android/text/util/Regex.java b/core/java/android/text/util/Regex.java index a6844a4..5005b42 100644 --- a/core/java/android/text/util/Regex.java +++ b/core/java/android/text/util/Regex.java @@ -43,7 +43,7 @@ public class Regex { + "|(jobs|j[emop])" + "|k[eghimnrwyz]" + "|l[abcikrstuvy]" - + "|(mil|mobi|museum|m[acdghklmnopqrstuvwxyz])" + + "|(mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])" + "|(name|net|n[acefgilopruz])" + "|(org|om)" + "|(pro|p[aefghklmnrstwy])" @@ -82,7 +82,7 @@ public class Regex { + "|(?:jobs|j[emop])" + "|k[eghimnrwyz]" + "|l[abcikrstuvy]" - + "|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])" + + "|(?:mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])" + "|(?:name|net|n[acefgilopruz])" + "|(?:org|om)" + "|(?:pro|p[aefghklmnrstwy])" diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index d4f9787..9aa16b5 100644..100755 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -120,6 +120,10 @@ public class KeyEvent implements Parcelable { public static final int KEYCODE_MEDIA_REWIND = 89; public static final int KEYCODE_MEDIA_FAST_FORWARD = 90; public static final int KEYCODE_MUTE = 91; + public static final int KEYCODE_PAGE_UP = 92; + public static final int KEYCODE_PAGE_DOWN = 93; + public static final int KEYCODE_PICTSYMBOLS = 94; // switch symbol-sets (Emoji,Kao-moji) + public static final int KEYCODE_SWITCH_CHARSET = 95; // switch char-sets (Kanji,Katakana) // NOTE: If you add a new keycode here you must also add it to: // isSystem() @@ -135,7 +139,7 @@ public class KeyEvent implements Parcelable { // those new codes. This is intended to maintain a consistent // set of key code definitions across all Android devices. - private static final int LAST_KEYCODE = KEYCODE_MUTE; + private static final int LAST_KEYCODE = KEYCODE_SWITCH_CHARSET; /** * @deprecated There are now more than MAX_KEYCODE keycodes. @@ -692,6 +696,8 @@ public class KeyEvent implements Parcelable { case KEYCODE_CAMERA: case KEYCODE_FOCUS: case KEYCODE_SEARCH: + case KEYCODE_PICTSYMBOLS: + case KEYCODE_SWITCH_CHARSET: return true; default: return false; diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java index 9a8ee02..b976378 100644 --- a/core/java/android/view/VelocityTracker.java +++ b/core/java/android/view/VelocityTracker.java @@ -190,7 +190,7 @@ public final class VelocityTracker implements Poolable<VelocityTracker> { final long oldestTime = pastTime[oldestTouch]; float accumX = 0; float accumY = 0; - float N = (lastTouch - oldestTouch + NUM_PAST) % NUM_PAST + 1; + int N = (lastTouch - oldestTouch + NUM_PAST) % NUM_PAST + 1; // Skip the last received event, since it is probably pretty noisy. if (N > 3) N--; diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 1fc3678..da48f40 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -8191,6 +8191,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility * Cancels any animations for this view. */ public void clearAnimation() { + if (mCurrentAnimation != null) { + mCurrentAnimation.detach(); + } mCurrentAnimation = null; } diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java index 000e4ce..11727b1 100644 --- a/core/java/android/view/animation/Animation.java +++ b/core/java/android/view/animation/Animation.java @@ -256,6 +256,38 @@ public abstract class Animation implements Cloneable { } /** + * Cancel the animation. Cancelling an animation invokes the animation + * listener, if set, to notify the end of the animation. + * + * If you cancel an animation manually, you must call {@link #reset()} + * before starting the animation again. + * + * @see #reset() + * @see #start() + * @see #startNow() + * @hide + */ + public void cancel() { + if (mStarted && !mEnded) { + if (mListener != null) mListener.onAnimationEnd(this); + mEnded = true; + } + // Make sure we move the animation to the end + mStartTime = Long.MIN_VALUE; + mMore = mOneMoreTime = false; + } + + /** + * @hide + */ + public void detach() { + if (mStarted && !mEnded) { + mEnded = true; + if (mListener != null) mListener.onAnimationEnd(this); + } + } + + /** * Whether or not the animation has been initialized. * * @return Has this animation been initialized. @@ -745,10 +777,10 @@ public abstract class Animation implements Cloneable { if (expired) { if (mRepeatCount == mRepeated) { if (!mEnded) { + mEnded = true; if (mListener != null) { mListener.onAnimationEnd(this); } - mEnded = true; } } else { if (mRepeatCount > 0) { diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java index fffba1b..60dfce7 100644 --- a/core/java/android/webkit/MimeTypeMap.java +++ b/core/java/android/webkit/MimeTypeMap.java @@ -67,7 +67,7 @@ public class MimeTypeMap { // if the filename contains special characters, we don't // consider it valid for our matching purposes: if (filename.length() > 0 && - Pattern.matches("[a-zA-Z_0-9\\.\\-\\(\\)]+", filename)) { + Pattern.matches("[a-zA-Z_0-9\\.\\-\\(\\)\\%]+", filename)) { int dotPos = filename.lastIndexOf('.'); if (0 <= dotPos) { return filename.substring(dotPos + 1); diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java index 5e76cc3..ebaf474 100644 --- a/core/java/android/widget/DatePicker.java +++ b/core/java/android/widget/DatePicker.java @@ -94,9 +94,7 @@ public class DatePicker extends FrameLayout { mDayPicker.setOnChangeListener(new OnChangedListener() { public void onChanged(NumberPicker picker, int oldVal, int newVal) { mDay = newVal; - if (mOnDateChangedListener != null) { - mOnDateChangedListener.onDateChanged(DatePicker.this, mYear, mMonth, mDay); - } + notifyDateChanged(); } }); mMonthPicker = (NumberPicker) findViewById(R.id.month); @@ -114,9 +112,7 @@ public class DatePicker extends FrameLayout { mMonth = newVal - 1; // Adjust max day of the month adjustMaxDay(); - if (mOnDateChangedListener != null) { - mOnDateChangedListener.onDateChanged(DatePicker.this, mYear, mMonth, mDay); - } + notifyDateChanged(); updateDaySpinner(); } }); @@ -127,9 +123,7 @@ public class DatePicker extends FrameLayout { mYear = newVal; // Adjust max day for leap years if needed adjustMaxDay(); - if (mOnDateChangedListener != null) { - mOnDateChangedListener.onDateChanged(DatePicker.this, mYear, mMonth, mDay); - } + notifyDateChanged(); updateDaySpinner(); } }); @@ -230,11 +224,14 @@ public class DatePicker extends FrameLayout { } public void updateDate(int year, int monthOfYear, int dayOfMonth) { - mYear = year; - mMonth = monthOfYear; - mDay = dayOfMonth; - updateSpinners(); - reorderPickers(new DateFormatSymbols().getShortMonths()); + if (mYear != year || mMonth != monthOfYear || mDay != dayOfMonth) { + mYear = year; + mMonth = monthOfYear; + mDay = dayOfMonth; + updateSpinners(); + reorderPickers(new DateFormatSymbols().getShortMonths()); + notifyDateChanged(); + } } private static class SavedState extends BaseSavedState { @@ -319,6 +316,7 @@ public class DatePicker extends FrameLayout { mYear = ss.getYear(); mMonth = ss.getMonth(); mDay = ss.getDay(); + updateSpinners(); } /** @@ -376,4 +374,10 @@ public class DatePicker extends FrameLayout { mDay = max; } } + + private void notifyDateChanged() { + if (mOnDateChangedListener != null) { + mOnDateChangedListener.onDateChanged(DatePicker.this, mYear, mMonth, mDay); + } + } } diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 6dc9f78..6393056 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -934,4 +934,20 @@ public class ProgressBar extends View { setProgress(ss.progress); setSecondaryProgress(ss.secondaryProgress); } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (mIndeterminate) { + startAnimation(); + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (mIndeterminate) { + stopAnimation(); + } + } } diff --git a/core/java/com/android/internal/view/IInputMethodSession.aidl b/core/java/com/android/internal/view/IInputMethodSession.aidl index a05ff14..338dcaa 100644 --- a/core/java/com/android/internal/view/IInputMethodSession.aidl +++ b/core/java/com/android/internal/view/IInputMethodSession.aidl @@ -48,4 +48,6 @@ oneway interface IInputMethodSession { void appPrivateCommand(String action, in Bundle data); void toggleSoftInput(int showFlags, int hideFlags); + + void finishSession(); } diff --git a/core/java/com/google/android/mms/ContentType.java b/core/java/com/google/android/mms/ContentType.java index 94bc9fd..b066fad 100644 --- a/core/java/com/google/android/mms/ContentType.java +++ b/core/java/com/google/android/mms/ContentType.java @@ -26,6 +26,7 @@ public class ContentType { public static final String MMS_GENERIC = "application/vnd.wap.mms-generic"; public static final String MULTIPART_MIXED = "application/vnd.wap.multipart.mixed"; public static final String MULTIPART_RELATED = "application/vnd.wap.multipart.related"; + public static final String MULTIPART_ALTERNATIVE = "application/vnd.wap.multipart.alternative"; public static final String TEXT_PLAIN = "text/plain"; public static final String TEXT_HTML = "text/html"; diff --git a/core/java/com/google/android/mms/pdu/PduParser.java b/core/java/com/google/android/mms/pdu/PduParser.java index d465c5a..1cd118b 100644 --- a/core/java/com/google/android/mms/pdu/PduParser.java +++ b/core/java/com/google/android/mms/pdu/PduParser.java @@ -200,7 +200,18 @@ public class PduParser { PduHeaders headers = new PduHeaders(); while (keepParsing && (pduDataStream.available() > 0)) { + pduDataStream.mark(1); int headerField = extractByteValue(pduDataStream); + /* parse custom text header */ + if ((headerField >= TEXT_MIN) && (headerField <= TEXT_MAX)) { + pduDataStream.reset(); + byte [] bVal = parseWapString(pduDataStream, TYPE_TEXT_STRING); + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "TextHeader: " + new String(bVal)); + } + /* we should ignore it at the moment */ + continue; + } switch (headerField) { case PduHeaders.MESSAGE_TYPE: { @@ -778,26 +789,34 @@ public class PduParser { /* get part's data */ if (dataLength > 0) { byte[] partData = new byte[dataLength]; + String partContentType = new String(part.getContentType()); pduDataStream.read(partData, 0, dataLength); - // Check Content-Transfer-Encoding. - byte[] partDataEncoding = part.getContentTransferEncoding(); - if (null != partDataEncoding) { - String encoding = new String(partDataEncoding); - if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) { - // Decode "base64" into "binary". - partData = Base64.decodeBase64(partData); - } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) { - // Decode "quoted-printable" into "binary". - partData = QuotedPrintable.decodeQuotedPrintable(partData); - } else { - // "binary" is the default encoding. + if (partContentType.equalsIgnoreCase(ContentType.MULTIPART_ALTERNATIVE)) { + // parse "multipart/vnd.wap.multipart.alternative". + PduBody childBody = parseParts(new ByteArrayInputStream(partData)); + // take the first part of children. + part = childBody.getPart(0); + } else { + // Check Content-Transfer-Encoding. + byte[] partDataEncoding = part.getContentTransferEncoding(); + if (null != partDataEncoding) { + String encoding = new String(partDataEncoding); + if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) { + // Decode "base64" into "binary". + partData = Base64.decodeBase64(partData); + } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) { + // Decode "quoted-printable" into "binary". + partData = QuotedPrintable.decodeQuotedPrintable(partData); + } else { + // "binary" is the default encoding. + } } + if (null == partData) { + log("Decode part data error!"); + return null; + } + part.setData(partData); } - if (null == partData) { - log("Decode part data error!"); - return null; - } - part.setData(partData); } /* add this part to body */ diff --git a/core/jni/android_database_SQLiteDatabase.cpp b/core/jni/android_database_SQLiteDatabase.cpp index 020aff4..f20dadb 100644 --- a/core/jni/android_database_SQLiteDatabase.cpp +++ b/core/jni/android_database_SQLiteDatabase.cpp @@ -262,7 +262,7 @@ static void native_setLocale(JNIEnv* env, jobject object, jstring localeString, goto done; } - dbLocale = (rowCount >= 1) ? meta[1 * colCount + 0] : NULL; + dbLocale = (rowCount >= 1) ? meta[colCount] : NULL; if (dbLocale != NULL && !strcmp(dbLocale, locale8)) { // database locale is the same as the desired locale; set up the collators and go @@ -273,7 +273,8 @@ static void native_setLocale(JNIEnv* env, jobject object, jstring localeString, if ((flags & OPEN_READONLY)) { // read-only database, so we're going to have to put up with whatever we got - err = register_localized_collators(handle, dbLocale ? dbLocale : locale8, UTF16_STORAGE); + // For registering new index. Not for modifing the read-only database. + err = register_localized_collators(handle, locale8, UTF16_STORAGE); if (err != SQLITE_OK) throw_sqlite3_exception(env, handle); goto done; } @@ -286,7 +287,7 @@ static void native_setLocale(JNIEnv* env, jobject object, jstring localeString, goto done; } - err = register_localized_collators(handle, dbLocale ? dbLocale : locale8, UTF16_STORAGE); + err = register_localized_collators(handle, locale8, UTF16_STORAGE); if (err != SQLITE_OK) { LOGE("register_localized_collators() failed setting locale\n"); throw_sqlite3_exception(env, handle); diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp index d2e9454..fdc97ee 100644 --- a/core/jni/android_server_BluetoothEventLoop.cpp +++ b/core/jni/android_server_BluetoothEventLoop.cpp @@ -564,7 +564,10 @@ static void *eventLoopMain(void *ptr) { NULL, NULL, NULL, NULL, NULL); tearDownEventLoop(nat); nat->vm->DetachCurrentThread(); - shutdown(nat->controlFdR,SHUT_RDWR); + + int fd = nat->controlFdR; + nat->controlFdR = 0; + close(fd); return NULL; } case EVENT_LOOP_ADD: @@ -653,9 +656,12 @@ static jboolean startEventLoopNative(JNIEnv *env, jobject object) { done: if (JNI_FALSE == result) { - if (nat->controlFdW || nat->controlFdR) { - shutdown(nat->controlFdW, SHUT_RDWR); + if (nat->controlFdW) { + close(nat->controlFdW); nat->controlFdW = 0; + } + if (nat->controlFdR) { + close(nat->controlFdR); nat->controlFdR = 0; } if (nat->me) env->DeleteGlobalRef(nat->me); @@ -692,9 +698,10 @@ static void stopEventLoopNative(JNIEnv *env, jobject object) { nat->watchData = NULL; nat->pollDataSize = 0; nat->pollMemberCount = 0; - shutdown(nat->controlFdW, SHUT_RDWR); + + int fd = nat->controlFdW; nat->controlFdW = 0; - nat->controlFdR = 0; + close(fd); } pthread_mutex_unlock(&(nat->thread_mutex)); #endif // HAVE_BLUETOOTH diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml index 66f0e82..e801ba8 100644 --- a/core/res/res/values/arrays.xml +++ b/core/res/res/values/arrays.xml @@ -113,11 +113,11 @@ <item><xliff:g id="id">phone_evdo_signal</xliff:g></item> <item><xliff:g id="id">data_connection</xliff:g></item> <item><xliff:g id="id">cdma_eri</xliff:g></item> + <item><xliff:g id="id">wifi</xliff:g></item> <item><xliff:g id="id">tty</xliff:g></item> <item><xliff:g id="id">volume</xliff:g></item> <item><xliff:g id="id">mute</xliff:g></item> <item><xliff:g id="id">speakerphone</xliff:g></item> - <item><xliff:g id="id">wifi</xliff:g></item> <item><xliff:g id="id">tty</xliff:g></item> <item><xliff:g id="id">bluetooth</xliff:g></item> <item><xliff:g id="id">gps</xliff:g></item> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 68661ae..a660fd9 100644..100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -912,6 +912,10 @@ <enum name="KEYCODE_MEDIA_REWIND" value="89" /> <enum name="KEYCODE_MEDIA_FAST_FORWARD" value="90" /> <enum name="KEYCODE_MUTE" value="91" /> + <enum name="KEYCODE_PAGE_UP" value="92" /> + <enum name="KEYCODE_PAGE_DOWN" value="93" /> + <enum name="KEYCODE_PICTSYMBOLS" value="94" /> + <enum name="KEYCODE_SWITCH_CHARSET" value="95" /> </attr> <!-- ***************************************************************** --> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 0327e08..df297b3 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -60,6 +60,10 @@ <!-- Displayed when the user dialed an MMI code whose function could not be performed. This will be displayed in a toast. --> <string name="mmiError">Connection problem or invalid MMI code.</string> + <!-- Displayed when the user dialed an MMI code whose function + could not be performed because FDN is enabled. This will be displayed in a toast. --> + <string name="mmiFdnError">Operation is restricted to fixed dialing numbers only.</string> + <!-- Displayed when a phone feature such as call barring was activated. --> <string name="serviceEnabled">Service was enabled.</string> <!-- Displayed in front of the list of a set of service classes diff --git a/docs/html/sitemap.txt b/docs/html/sitemap.txt index f82b2fe..5039dfc 100644 --- a/docs/html/sitemap.txt +++ b/docs/html/sitemap.txt @@ -2864,11 +2864,6 @@ http://developer.android.com/reference/org/xmlpull/v1/XmlSerializer.html http://developer.android.com/reference/org/apache/http/cookie/params/package-descr.html http://developer.android.com/reference/java/util/concurrent/locks/package-descr.html http://developer.android.com/reference/org/apache/http/conn/routing/package-descr.html -http://developer.android.com/guide/samples/index.html -http://developer.android.com/guide/tutorials/notepad/notepad-ex1.html -http://developer.android.com/guide/tutorials/notepad/notepad-ex2.html -http://developer.android.com/guide/tutorials/notepad/notepad-ex3.html -http://developer.android.com/guide/tutorials/notepad/notepad-extra-credit.html http://developer.android.com/guide/appendix/faq/commontasks.html http://developer.android.com/reference/javax/security/cert/package-descr.html http://developer.android.com/reference/org/xml/sax/ext/package-descr.html @@ -3029,7 +3024,6 @@ http://developer.android.com/reference/javax/security/auth/x500/package-descr.ht http://developer.android.com/sdk/api_diff/6/changes/android.view.WindowManager.LayoutParams.html http://developer.android.com/reference/android/net/package-descr.html http://developer.android.com/reference/org/apache/http/client/package-descr.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html http://developer.android.com/sdk/download.html?v=archives/android-sdk-windows-1.6_r1.zip http://developer.android.com/sdk/download.html?v=archives/android-sdk-mac_x86-1.6_r1.zip http://developer.android.com/sdk/download.html?v=archives/android-sdk-linux_x86-1.6_r1.tgz @@ -3299,7 +3293,6 @@ http://developer.android.com/resources/samples/BluetoothChat/res/layout/main.htm http://developer.android.com/resources/samples/BluetoothChat/res/layout/message.html http://developer.android.com/resources/samples/NotePad/res/drawable-ldpi-v6/app_notes.html http://developer.android.com/resources/samples/NotePad/res/drawable-ldpi-v6/live_folder_notes.html -http://developer.android.com/guide/tutorials/views/index.html http://developer.android.com/sdk/api_diff/4/changes/pkg_android.html http://developer.android.com/sdk/api_diff/4/changes/pkg_android.app.html http://developer.android.com/sdk/api_diff/4/changes/pkg_android.content.res.html @@ -3523,21 +3516,6 @@ http://developer.android.com/reference/javax/security/auth/login/package-descr.h http://developer.android.com/resources/samples/ApiDemos/tests/src/com/example/android/apis/index.html http://developer.android.com/reference/org/apache/http/conn/ssl/package-descr.html http://developer.android.com/resources/samples/ContactManager/res/drawable-hdpi/icon.html -http://developer.android.com/guide/tutorials/views/hello-linearlayout.html -http://developer.android.com/guide/tutorials/views/hello-relativelayout.html -http://developer.android.com/guide/tutorials/views/hello-tablelayout.html -http://developer.android.com/guide/tutorials/views/hello-datepicker.html -http://developer.android.com/guide/tutorials/views/hello-timepicker.html -http://developer.android.com/guide/tutorials/views/hello-formstuff.html -http://developer.android.com/guide/tutorials/views/hello-spinner.html -http://developer.android.com/guide/tutorials/views/hello-autocomplete.html -http://developer.android.com/guide/tutorials/views/hello-listview.html -http://developer.android.com/guide/tutorials/views/hello-gridview.html -http://developer.android.com/guide/tutorials/views/hello-gallery.html -http://developer.android.com/guide/tutorials/views/hello-tabwidget.html -http://developer.android.com/guide/tutorials/views/hello-mapview.html -http://developer.android.com/guide/tutorials/views/hello-webview.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/index.html http://developer.android.com/sdk/api_diff/5/changes/packages_index_all.html http://developer.android.com/sdk/api_diff/5/changes/classes_index_all.html http://developer.android.com/sdk/api_diff/5/changes/constructors_index_all.html @@ -3858,112 +3836,6 @@ http://developer.android.com/resources/samples/Home/res/anim/show_applications.h http://developer.android.com/reference/org/w3c/dom/package-descr.html http://developer.android.com/reference/org/apache/http/package-descr.html http://developer.android.com/resources/samples/MultiResolution/src/com/example/index.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/RelativeLayout1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/RelativeLayout2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout4.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout5.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout6.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout7.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout8.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout9.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollView1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout4.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout5.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout6.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout7.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout8.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout9.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline4.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline6.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline7.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/RadioGroup1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Visibility1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List4.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List5.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List6.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List7.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List8.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/CustomView1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ImageButton1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/DateWidgets1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/DateWidgets2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Spinner1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Grid1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Grid2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TextSwitcher1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Animation1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Animation2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Controls1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Controls2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar4.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Focus1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Focus2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Focus3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Animation3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ChronometerDemo.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ImageView1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionFocus.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionScroll.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionView.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LabelView.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation4.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation5.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation6.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation7.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout10.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List10.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List11.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List12.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List13.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List14.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List9.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/SeekBar1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Tabs2.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Tabs3.html -http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/WebView1.html http://developer.android.com/resources/samples/Home/res/drawable/all_applications.html http://developer.android.com/resources/samples/Home/res/drawable/all_applications_background.html http://developer.android.com/resources/samples/Home/res/drawable/all_applications_button_background.html diff --git a/graphics/java/android/graphics/Color.java b/graphics/java/android/graphics/Color.java index 5cefaa3..a50693d 100644 --- a/graphics/java/android/graphics/Color.java +++ b/graphics/java/android/graphics/Color.java @@ -30,7 +30,8 @@ import java.util.Locale; * (green << 8) | blue. Each component ranges between 0..255 with 0 * meaning no contribution for that component, and 255 meaning 100% * contribution. Thus opaque-black would be 0xFF000000 (100% opaque but - * no contributes from red, gree, blue, and opaque-white would be 0xFFFFFFFF + * no contributions from red, green, or blue), and opaque-white would be + * 0xFFFFFFFF */ public class Color { public static final int BLACK = 0xFF000000; diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 91a2bc1..63d1446 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -778,8 +778,8 @@ public class GradientDrawable extends Drawable { com.android.internal.R.styleable.DrawableCorners_bottomLeftRadius, radius); int bottomRightRadius = a.getDimensionPixelSize( com.android.internal.R.styleable.DrawableCorners_bottomRightRadius, radius); - if (topLeftRadius != radius && topRightRadius != radius && - bottomLeftRadius != radius && bottomRightRadius != radius) { + if (topLeftRadius != radius || topRightRadius != radius || + bottomLeftRadius != radius || bottomRightRadius != radius) { setCornerRadii(new float[] { topLeftRadius, topLeftRadius, topRightRadius, topRightRadius, diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index b6ac14a..e5cf38e 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -39,15 +39,17 @@ public class Allocation extends BaseObj { mType = t; } + public Type getType() { + return mType; + } + public void uploadToTexture(int baseMipLevel) { mRS.validate(); - mRS.validateSurface(); mRS.nAllocationUploadToTexture(mID, baseMipLevel); } public void uploadToBufferObject() { mRS.validate(); - mRS.validateSurface(); mRS.nAllocationUploadToBufferObject(mID); } @@ -171,9 +173,10 @@ public class Allocation extends BaseObj { public Adapter1D createAdapter1D() { mRS.validate(); int id = mRS.nAdapter1DCreate(); - if (id != 0) { - mRS.nAdapter1DBindAllocation(id, mID); + if(id == 0) { + throw new IllegalStateException("allocation failed."); } + mRS.nAdapter1DBindAllocation(id, mID); return new Adapter1D(id, mRS); } @@ -213,9 +216,10 @@ public class Allocation extends BaseObj { public Adapter2D createAdapter2D() { mRS.validate(); int id = mRS.nAdapter2DCreate(); - if (id != 0) { - mRS.nAdapter2DBindAllocation(id, mID); + if(id == 0) { + throw new IllegalStateException("allocation failed."); } + mRS.nAdapter2DBindAllocation(id, mID); return new Adapter2D(id, mRS); } @@ -258,14 +262,20 @@ public class Allocation extends BaseObj { rs.validate(); int id = rs.nAllocationCreateFromBitmap(dstFmt.mID, genMips, b); + if(id == 0) { + throw new IllegalStateException("Load failed."); + } return new Allocation(id, rs, null); } - static public Allocation createFromBitmapBoxed(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips) + static Allocation createFromBitmapBoxed(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips) throws IllegalArgumentException { rs.validate(); int id = rs.nAllocationCreateFromBitmapBoxed(dstFmt.mID, genMips, b); + if(id == 0) { + throw new IllegalStateException("Load failed."); + } return new Allocation(id, rs, null); } @@ -282,6 +292,9 @@ public class Allocation extends BaseObj { int allocationId = rs.nAllocationCreateFromAssetStream(dstFmt.mID, genMips, asset); + if(allocationId == 0) { + throw new IllegalStateException("Load failed."); + } return new Allocation(allocationId, rs, null); } catch (Exception e) { // Ignore diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java index e802ec5..002fc78 100644 --- a/graphics/java/android/renderscript/BaseObj.java +++ b/graphics/java/android/renderscript/BaseObj.java @@ -25,6 +25,7 @@ import android.util.Log; class BaseObj { BaseObj(RenderScript rs) { + rs.validate(); mRS = rs; mID = 0; mDestroyed = false; diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java index ee9b098..10ef05a 100644 --- a/graphics/java/android/renderscript/Element.java +++ b/graphics/java/android/renderscript/Element.java @@ -24,259 +24,220 @@ import java.lang.reflect.Field; **/ public class Element extends BaseObj { int mSize; - Entry[] mEntries; + Element[] mElements; + String[] mElementNames; - int getSizeBytes() { - return mSize; - } - int getComponentCount() { - return mEntries.length; - } - Element.DataType getComponentDataType(int num) { - return mEntries[num].mType; - } - Element.DataKind getComponentDataKind(int num) { - return mEntries[num].mKind; - } - boolean getComponentIsNormalized(int num) { - return mEntries[num].mIsNormalized; - } - int getComponentBits(int num) { - return mEntries[num].mBits; - } - String getComponentName(int num) { - return mEntries[num].mName; + DataType mType; + DataKind mKind; + boolean mNormalized; + int mVectorSize; + + int getSizeBytes() {return mSize;} + + public enum DataType { + //FLOAT_16 (1, 2), + FLOAT_32 (2, 4), + //FLOAT_64 (3, 8), + SIGNED_8 (4, 1), + SIGNED_16 (5, 2), + SIGNED_32 (6, 4), + //SIGNED_64 (7, 8), + UNSIGNED_8 (8, 1), + UNSIGNED_16 (9, 2), + UNSIGNED_32 (10, 4), + //UNSIGNED_64 (11, 8), + + UNSIGNED_5_6_5 (12, 2), + UNSIGNED_5_5_5_1 (13, 2), + UNSIGNED_4_4_4_4 (14, 2), + + RS_ELEMENT (15, 4), + RS_TYPE (16, 4), + RS_ALLOCATION (17, 4), + RS_SAMPLER (18, 4), + RS_SCRIPT (19, 4), + RS_MESH (20, 4), + RS_PROGRAM_FRAGMENT (21, 4), + RS_PROGRAM_VERTEX (22, 4), + RS_PROGRAM_RASTER (23, 4), + RS_PROGRAM_STORE (24, 4); + + int mID; + int mSize; + DataType(int id, int size) { + mID = id; + mSize = size; + } } - static class Entry { - //Element mElement; - Element.DataType mType; - Element.DataKind mKind; - boolean mIsNormalized; - int mBits; - String mName; - - //Entry(Element e, int bits) { - //mElement = e; - //int mBits = bits; - //} - - Entry(DataType dt, DataKind dk, boolean isNorm, int bits, String name) { - mType = dt; - mKind = dk; - mIsNormalized = isNorm; - mBits = bits; - mName = name; + public enum DataKind { + USER (0), + COLOR (1), + POSITION (2), + TEXTURE (3), + NORMAL (4), + INDEX (5), + POINT_SIZE(6), + + PIXEL_L (7), + PIXEL_A (8), + PIXEL_LA (9), + PIXEL_RGB (10), + PIXEL_RGBA (11); + + int mID; + DataKind(int id) { + mID = id; } } public static Element USER_U8(RenderScript rs) { if(rs.mElement_USER_U8 == null) { - rs.mElement_USER_U8 = new Element(rs, 1); - rs.mElement_USER_U8.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.USER, false, 8, null); - rs.mElement_USER_U8.init(); + rs.mElement_USER_U8 = createUser(rs, DataType.UNSIGNED_8); } return rs.mElement_USER_U8; } public static Element USER_I8(RenderScript rs) { if(rs.mElement_USER_I8 == null) { - rs.mElement_USER_I8 = new Element(rs, 1); - rs.mElement_USER_I8.mEntries[0] = new Entry(DataType.SIGNED, DataKind.USER, false, 8, null); - rs.mElement_USER_I8.init(); + rs.mElement_USER_I8 = createUser(rs, DataType.SIGNED_8); } return rs.mElement_USER_I8; } - public static Element USER_U16(RenderScript rs) { - if(rs.mElement_USER_U16 == null) { - rs.mElement_USER_U16 = new Element(rs, 1); - rs.mElement_USER_U16.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.USER, false, 16, null); - rs.mElement_USER_U16.init(); - } - return rs.mElement_USER_U16; - } - - public static Element USER_I16(RenderScript rs) { - if(rs.mElement_USER_I16 == null) { - rs.mElement_USER_I16 = new Element(rs, 1); - rs.mElement_USER_I16.mEntries[0] = new Entry(DataType.SIGNED, DataKind.USER, false, 16, null); - rs.mElement_USER_I16.init(); - } - return rs.mElement_USER_I16; - } - public static Element USER_U32(RenderScript rs) { if(rs.mElement_USER_U32 == null) { - rs.mElement_USER_U32 = new Element(rs, 1); - rs.mElement_USER_U32.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.USER, false, 32, null); - rs.mElement_USER_U32.init(); + rs.mElement_USER_U32 = createUser(rs, DataType.UNSIGNED_32); } return rs.mElement_USER_U32; } public static Element USER_I32(RenderScript rs) { if(rs.mElement_USER_I32 == null) { - rs.mElement_USER_I32 = new Element(rs, 1); - rs.mElement_USER_I32.mEntries[0] = new Entry(DataType.SIGNED, DataKind.USER, false, 32, null); - rs.mElement_USER_I32.init(); + rs.mElement_USER_I32 = createUser(rs, DataType.SIGNED_32); } return rs.mElement_USER_I32; } public static Element USER_F32(RenderScript rs) { - if(rs.mElement_USER_FLOAT == null) { - rs.mElement_USER_FLOAT = new Element(rs, 1); - rs.mElement_USER_FLOAT.mEntries[0] = new Entry(DataType.FLOAT, DataKind.USER, false, 32, null); - rs.mElement_USER_FLOAT.init(); + if(rs.mElement_USER_F32 == null) { + rs.mElement_USER_F32 = createUser(rs, DataType.FLOAT_32); } - return rs.mElement_USER_FLOAT; + return rs.mElement_USER_F32; } public static Element A_8(RenderScript rs) { if(rs.mElement_A_8 == null) { - rs.mElement_A_8 = new Element(rs, 1); - rs.mElement_A_8.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 8, "a"); - rs.mElement_A_8.init(); + rs.mElement_A_8 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_A); } return rs.mElement_A_8; } public static Element RGB_565(RenderScript rs) { if(rs.mElement_RGB_565 == null) { - rs.mElement_RGB_565 = new Element(rs, 3); - rs.mElement_RGB_565.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 5, "r"); - rs.mElement_RGB_565.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 6, "g"); - rs.mElement_RGB_565.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 5, "b"); - rs.mElement_RGB_565.init(); + rs.mElement_RGB_565 = createPixel(rs, DataType.UNSIGNED_5_6_5, DataKind.PIXEL_RGB); } return rs.mElement_RGB_565; } public static Element RGB_888(RenderScript rs) { if(rs.mElement_RGB_888 == null) { - rs.mElement_RGB_888 = new Element(rs, 3); - rs.mElement_RGB_888.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 8, "r"); - rs.mElement_RGB_888.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 8, "g"); - rs.mElement_RGB_888.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 8, "b"); - rs.mElement_RGB_888.init(); + rs.mElement_RGB_888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGB); } return rs.mElement_RGB_888; } public static Element RGBA_5551(RenderScript rs) { if(rs.mElement_RGBA_5551 == null) { - rs.mElement_RGBA_5551 = new Element(rs, 4); - rs.mElement_RGBA_5551.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 5, "r"); - rs.mElement_RGBA_5551.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 5, "g"); - rs.mElement_RGBA_5551.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 5, "b"); - rs.mElement_RGBA_5551.mEntries[3] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 1, "a"); - rs.mElement_RGBA_5551.init(); + rs.mElement_RGBA_5551 = createPixel(rs, DataType.UNSIGNED_5_5_5_1, DataKind.PIXEL_RGBA); } return rs.mElement_RGBA_5551; } public static Element RGBA_4444(RenderScript rs) { if(rs.mElement_RGBA_4444 == null) { - rs.mElement_RGBA_4444 = new Element(rs, 4); - rs.mElement_RGBA_4444.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 4, "r"); - rs.mElement_RGBA_4444.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 4, "g"); - rs.mElement_RGBA_4444.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 4, "b"); - rs.mElement_RGBA_4444.mEntries[3] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 4, "a"); - rs.mElement_RGBA_4444.init(); + rs.mElement_RGBA_4444 = createPixel(rs, DataType.UNSIGNED_4_4_4_4, DataKind.PIXEL_RGBA); } return rs.mElement_RGBA_4444; } public static Element RGBA_8888(RenderScript rs) { if(rs.mElement_RGBA_8888 == null) { - rs.mElement_RGBA_8888 = new Element(rs, 4); - rs.mElement_RGBA_8888.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 8, "r"); - rs.mElement_RGBA_8888.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 8, "g"); - rs.mElement_RGBA_8888.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 8, "b"); - rs.mElement_RGBA_8888.mEntries[3] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 8, "a"); - rs.mElement_RGBA_8888.init(); + rs.mElement_RGBA_8888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGBA); } return rs.mElement_RGBA_8888; } public static Element INDEX_16(RenderScript rs) { if(rs.mElement_INDEX_16 == null) { - rs.mElement_INDEX_16 = new Element(rs, 1); - rs.mElement_INDEX_16.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.INDEX, false, 16, "index"); - rs.mElement_INDEX_16.init(); + rs.mElement_INDEX_16 = createIndex(rs); } return rs.mElement_INDEX_16; } - public static Element XY_F32(RenderScript rs) { - if(rs.mElement_XY_F32 == null) { - rs.mElement_XY_F32 = new Element(rs, 2); - rs.mElement_XY_F32.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.X, false, 32, "x"); - rs.mElement_XY_F32.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.Y, false, 32, "y"); - rs.mElement_XY_F32.init(); + public static Element ATTRIB_POSITION_2(RenderScript rs) { + if(rs.mElement_POSITION_2 == null) { + rs.mElement_POSITION_2 = createAttrib(rs, DataType.FLOAT_32, DataKind.POSITION, 2); } - return rs.mElement_XY_F32; + return rs.mElement_POSITION_2; } - public static Element XYZ_F32(RenderScript rs) { - if(rs.mElement_XYZ_F32 == null) { - rs.mElement_XYZ_F32 = new Element(rs, 3); - rs.mElement_XYZ_F32.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.X, false, 32, "x"); - rs.mElement_XYZ_F32.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.Y, false, 32, "y"); - rs.mElement_XYZ_F32.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.Z, false, 32, "z"); - rs.mElement_XYZ_F32.init(); + public static Element ATTRIB_POSITION_3(RenderScript rs) { + if(rs.mElement_POSITION_3 == null) { + rs.mElement_POSITION_3 = createAttrib(rs, DataType.FLOAT_32, DataKind.POSITION, 3); } - return rs.mElement_XYZ_F32; + return rs.mElement_POSITION_3; } - static void initPredefined(RenderScript rs) { - rs.nInitElements(A_8(rs).mID, RGBA_4444(rs).mID, RGBA_8888(rs).mID, RGB_565(rs).mID); + public static Element ATTRIB_TEXTURE_2(RenderScript rs) { + if(rs.mElement_TEXTURE_2 == null) { + rs.mElement_TEXTURE_2 = createAttrib(rs, DataType.FLOAT_32, DataKind.TEXTURE, 2); + } + return rs.mElement_TEXTURE_2; } - public enum DataType { - FLOAT (0), - UNSIGNED (1), - SIGNED (2); - - int mID; - DataType(int id) { - mID = id; + public static Element ATTRIB_NORMAL_3(RenderScript rs) { + if(rs.mElement_NORMAL_3 == null) { + rs.mElement_NORMAL_3 = createAttrib(rs, DataType.FLOAT_32, DataKind.NORMAL, 3); } + return rs.mElement_NORMAL_3; } - public enum DataKind { - USER (0), - RED (1), - GREEN (2), - BLUE (3), - ALPHA (4), - LUMINANCE (5), - INTENSITY (6), - X (7), - Y (8), - Z (9), - W (10), - S (11), - T (12), - Q (13), - R (14), - NX (15), - NY (16), - NZ (17), - INDEX (18), - POINT_SIZE(19); + public static Element ATTRIB_COLOR_U8_4(RenderScript rs) { + if(rs.mElement_COLOR_U8_4 == null) { + rs.mElement_COLOR_U8_4 = createAttrib(rs, DataType.UNSIGNED_8, DataKind.COLOR, 4); + } + return rs.mElement_COLOR_U8_4; + } - int mID; - DataKind(int id) { - mID = id; + public static Element ATTRIB_COLOR_F32_4(RenderScript rs) { + if(rs.mElement_COLOR_F32_4 == null) { + rs.mElement_COLOR_F32_4 = createAttrib(rs, DataType.FLOAT_32, DataKind.COLOR, 4); } + return rs.mElement_COLOR_F32_4; } - Element(RenderScript rs, int count) { + Element(RenderScript rs, Element[] e, String[] n) { super(rs); mSize = 0; - mEntries = new Entry[count]; + mElements = e; + mElementNames = n; + int[] ids = new int[mElements.length]; + for (int ct = 0; ct < mElements.length; ct++ ) { + mSize += mElements[ct].mSize; + ids[ct] = mElements[ct].mID; + } + mID = rs.nElementCreate2(ids, mElementNames); + } + + Element(RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) { + super(rs); + mSize = dt.mSize * size; + mType = dt; + mKind = dk; + mNormalized = norm; + mVectorSize = size; + mID = rs.nElementCreate(dt.mID, dk.mID, norm, size); } public void destroy() throws IllegalStateException { @@ -291,13 +252,13 @@ public class Element extends BaseObj { for(Field f: fields) { Class fc = f.getType(); if(fc == int.class) { - b.add(Element.DataType.SIGNED, Element.DataKind.USER, false, 32, f.getName()); + b.add(createUser(rs, DataType.SIGNED_32), f.getName()); } else if(fc == short.class) { - b.add(Element.DataType.SIGNED, Element.DataKind.USER, false, 16, f.getName()); + b.add(createUser(rs, DataType.SIGNED_16), f.getName()); } else if(fc == byte.class) { - b.add(Element.DataType.SIGNED, Element.DataKind.USER, false, 8, f.getName()); + b.add(createUser(rs, DataType.SIGNED_8), f.getName()); } else if(fc == float.class) { - b.add(Element.DataType.FLOAT, Element.DataKind.USER, false, 32, f.getName()); + b.add(createUser(rs, DataType.FLOAT_32), f.getName()); } else { throw new IllegalArgumentException("Unkown field type"); } @@ -305,193 +266,157 @@ public class Element extends BaseObj { return b.create(); } - static synchronized void internalCreate(RenderScript rs, Element e) { - rs.nElementBegin(); - int bits = 0; - for (int ct=0; ct < e.mEntries.length; ct++) { - Entry en = e.mEntries[ct]; - //if(en.mElement != null) { - //rs.nElementAdd(en.mElement.mID); - //} else - { - rs.nElementAdd(en.mKind.mID, en.mType.mID, en.mIsNormalized, en.mBits, en.mName); - bits += en.mBits; - } - } - e.mID = rs.nElementCreate(); - e.mSize = (bits + 7) >> 3; - } - void init() { - mRS.validate(); - internalCreate(mRS, this); + ///////////////////////////////////////// + public static Element createUser(RenderScript rs, DataType dt) { + return new Element(rs, dt, DataKind.USER, false, 1); } - - public static class Builder { - RenderScript mRS; - Entry[] mEntries; - int mEntryCount; - - public Builder(RenderScript rs) { - mRS = rs; - mEntryCount = 0; - mEntries = new Entry[8]; - } - - void addEntry(Entry e) { - if(mEntries.length >= mEntryCount) { - Entry[] en = new Entry[mEntryCount + 8]; - System.arraycopy(mEntries, 0, en, 0, mEntries.length); - mEntries = en; - } - mEntries[mEntryCount] = e; - mEntryCount++; + public static Element createVector(RenderScript rs, DataType dt, int size) { + if (size < 2 || size > 4) { + throw new IllegalArgumentException("Bad size"); } + return new Element(rs, dt, DataKind.USER, false, size); + } - //public Builder add(Element e) throws IllegalArgumentException { - //Entry en = new Entry(e, e.mSize * 8); - //addEntry(en); - //return this; - //} + public static Element createIndex(RenderScript rs) { + return new Element(rs, DataType.UNSIGNED_16, DataKind.INDEX, false, 1); + } - public Builder add(Element.DataType dt, Element.DataKind dk, boolean isNormalized, int bits, String name) { - Entry en = new Entry(dt, dk, isNormalized, bits, name); - addEntry(en); - return this; + public static Element createAttrib(RenderScript rs, DataType dt, DataKind dk, int size) { + if (!(dt == DataType.FLOAT_32 || + dt == DataType.UNSIGNED_8 || + dt == DataType.UNSIGNED_16 || + dt == DataType.UNSIGNED_32 || + dt == DataType.SIGNED_8 || + dt == DataType.SIGNED_16 || + dt == DataType.SIGNED_32)) { + throw new IllegalArgumentException("Unsupported DataType"); } - public Builder add(Element.DataType dt, Element.DataKind dk, boolean isNormalized, int bits) { - add(dt, dk, isNormalized, bits, null); - return this; + if (!(dk == DataKind.COLOR || + dk == DataKind.POSITION || + dk == DataKind.TEXTURE || + dk == DataKind.NORMAL || + dk == DataKind.POINT_SIZE || + dk == DataKind.USER)) { + throw new IllegalArgumentException("Unsupported DataKind"); } - public Builder addFloat(Element.DataKind dk) { - add(DataType.FLOAT, dk, false, 32, null); - return this; + if (dk == DataKind.COLOR && + ((dt != DataType.FLOAT_32 && dt != DataType.UNSIGNED_8) || + size < 3 || size > 4)) { + throw new IllegalArgumentException("Bad combo"); } - - public Builder addFloat(Element.DataKind dk, String name) { - add(DataType.FLOAT, dk, false, 32, name); - return this; + if (dk == DataKind.POSITION && (size < 1 || size > 4)) { + throw new IllegalArgumentException("Bad combo"); } - - public Builder addFloatXY() { - add(DataType.FLOAT, DataKind.X, false, 32, null); - add(DataType.FLOAT, DataKind.Y, false, 32, null); - return this; + if (dk == DataKind.TEXTURE && + (dt != DataType.FLOAT_32 || size < 1 || size > 4)) { + throw new IllegalArgumentException("Bad combo"); } - - public Builder addFloatXY(String prefix) { - add(DataType.FLOAT, DataKind.X, false, 32, prefix + "x"); - add(DataType.FLOAT, DataKind.Y, false, 32, prefix + "y"); - return this; + if (dk == DataKind.NORMAL && + (dt != DataType.FLOAT_32 || size != 3)) { + throw new IllegalArgumentException("Bad combo"); } - - public Builder addFloatXYZ() { - add(DataType.FLOAT, DataKind.X, false, 32, null); - add(DataType.FLOAT, DataKind.Y, false, 32, null); - add(DataType.FLOAT, DataKind.Z, false, 32, null); - return this; + if (dk == DataKind.POINT_SIZE && + (dt != DataType.FLOAT_32 || size != 1)) { + throw new IllegalArgumentException("Bad combo"); } - public Builder addFloatXYZ(String prefix) { - add(DataType.FLOAT, DataKind.X, false, 32, prefix + "x"); - add(DataType.FLOAT, DataKind.Y, false, 32, prefix + "y"); - add(DataType.FLOAT, DataKind.Z, false, 32, prefix + "z"); - return this; + boolean norm = false; + if (dk == DataKind.COLOR && dt == DataType.UNSIGNED_8) { + norm = true; } - public Builder addFloatST() { - add(DataType.FLOAT, DataKind.S, false, 32, null); - add(DataType.FLOAT, DataKind.T, false, 32, null); - return this; - } + return new Element(rs, dt, dk, norm, size); + } - public Builder addFloatST(String prefix) { - add(DataType.FLOAT, DataKind.S, false, 32, prefix + "s"); - add(DataType.FLOAT, DataKind.T, false, 32, prefix + "t"); - return this; + public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) { + if (!(dk == DataKind.PIXEL_L || + dk == DataKind.PIXEL_A || + dk == DataKind.PIXEL_LA || + dk == DataKind.PIXEL_RGB || + dk == DataKind.PIXEL_RGBA)) { + throw new IllegalArgumentException("Unsupported DataKind"); } - - public Builder addFloatNorm() { - add(DataType.FLOAT, DataKind.NX, false, 32, null); - add(DataType.FLOAT, DataKind.NY, false, 32, null); - add(DataType.FLOAT, DataKind.NZ, false, 32, null); - return this; + if (!(dt == DataType.UNSIGNED_8 || + dt == DataType.UNSIGNED_5_6_5 || + dt == DataType.UNSIGNED_4_4_4_4 || + dt == DataType.UNSIGNED_5_5_5_1)) { + throw new IllegalArgumentException("Unsupported DataType"); } - - public Builder addFloatNorm(String prefix) { - add(DataType.FLOAT, DataKind.NX, false, 32, prefix + "nx"); - add(DataType.FLOAT, DataKind.NY, false, 32, prefix + "ny"); - add(DataType.FLOAT, DataKind.NZ, false, 32, prefix + "nz"); - return this; + if (dt == DataType.UNSIGNED_5_6_5 && dk != DataKind.PIXEL_RGB) { + throw new IllegalArgumentException("Bad kind and type combo"); } - - public Builder addFloatPointSize() { - add(DataType.FLOAT, DataKind.POINT_SIZE, false, 32, null); - return this; + if (dt == DataType.UNSIGNED_5_5_5_1 && dk != DataKind.PIXEL_RGBA) { + throw new IllegalArgumentException("Bad kind and type combo"); } - - public Builder addFloatPointSize(String prefix) { - add(DataType.FLOAT, DataKind.POINT_SIZE, false, 32, prefix + "pointSize"); - return this; + if (dt == DataType.UNSIGNED_4_4_4_4 && dk != DataKind.PIXEL_RGBA) { + throw new IllegalArgumentException("Bad kind and type combo"); } - public Builder addFloatRGB() { - add(DataType.FLOAT, DataKind.RED, false, 32, null); - add(DataType.FLOAT, DataKind.GREEN, false, 32, null); - add(DataType.FLOAT, DataKind.BLUE, false, 32, null); - return this; + int size = 1; + if (dk == DataKind.PIXEL_LA) { + size = 2; } - - public Builder addFloatRGB(String prefix) { - add(DataType.FLOAT, DataKind.RED, false, 32, prefix + "r"); - add(DataType.FLOAT, DataKind.GREEN, false, 32, prefix + "g"); - add(DataType.FLOAT, DataKind.BLUE, false, 32, prefix + "b"); - return this; + if (dk == DataKind.PIXEL_RGB) { + size = 3; } - - public Builder addFloatRGBA() { - add(DataType.FLOAT, DataKind.RED, false, 32, null); - add(DataType.FLOAT, DataKind.GREEN, false, 32, null); - add(DataType.FLOAT, DataKind.BLUE, false, 32, null); - add(DataType.FLOAT, DataKind.ALPHA, false, 32, null); - return this; + if (dk == DataKind.PIXEL_RGBA) { + size = 4; } - public Builder addFloatRGBA(String prefix) { - add(DataType.FLOAT, DataKind.RED, false, 32, prefix + "r"); - add(DataType.FLOAT, DataKind.GREEN, false, 32, prefix + "g"); - add(DataType.FLOAT, DataKind.BLUE, false, 32, prefix + "b"); - add(DataType.FLOAT, DataKind.ALPHA, false, 32, prefix + "a"); - return this; - } + return new Element(rs, dt, dk, true, size); + } - public Builder addUNorm8RGBA() { - add(DataType.UNSIGNED, DataKind.RED, true, 8, null); - add(DataType.UNSIGNED, DataKind.GREEN, true, 8, null); - add(DataType.UNSIGNED, DataKind.BLUE, true, 8, null); - add(DataType.UNSIGNED, DataKind.ALPHA, true, 8, null); - return this; - } + public static class Builder { + RenderScript mRS; + Element[] mElements; + String[] mElementNames; + int mCount; - public Builder addUNorm8RGBA(String prefix) { - add(DataType.UNSIGNED, DataKind.RED, true, 8, prefix + "r"); - add(DataType.UNSIGNED, DataKind.GREEN, true, 8, prefix + "g"); - add(DataType.UNSIGNED, DataKind.BLUE, true, 8, prefix + "b"); - add(DataType.UNSIGNED, DataKind.ALPHA, true, 8, prefix + "a"); - return this; + public Builder(RenderScript rs) { + mRS = rs; + mCount = 0; + mElements = new Element[8]; + mElementNames = new String[8]; + } + + public void add(Element element, String name) { + if(mCount == mElements.length) { + Element[] e = new Element[mCount + 8]; + String[] s = new String[mCount + 8]; + System.arraycopy(mElements, 0, e, 0, mCount); + System.arraycopy(mElementNames, 0, s, 0, mCount); + mElements = e; + mElementNames = s; + } + mElements[mCount] = element; + mElementNames[mCount] = name; + mCount++; } public Element create() { mRS.validate(); - Element e = new Element(mRS, mEntryCount); - java.lang.System.arraycopy(mEntries, 0, e.mEntries, 0, mEntryCount); - e.init(); - return e; + Element[] ein = new Element[mCount]; + String[] sin = new String[mCount]; + java.lang.System.arraycopy(mElements, 0, ein, 0, mCount); + java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount); + return new Element(mRS, ein, sin); } } + static void initPredefined(RenderScript rs) { + int a8 = rs.nElementCreate(DataType.UNSIGNED_8.mID, + DataKind.PIXEL_A.mID, true, 1); + int rgba4444 = rs.nElementCreate(DataType.UNSIGNED_4_4_4_4.mID, + DataKind.PIXEL_RGBA.mID, true, 4); + int rgba8888 = rs.nElementCreate(DataType.UNSIGNED_8.mID, + DataKind.PIXEL_RGBA.mID, true, 4); + int rgb565 = rs.nElementCreate(DataType.UNSIGNED_5_6_5.mID, + DataKind.PIXEL_RGB.mID, true, 3); + rs.nInitElements(a8, rgba4444, rgba8888, rgb565); + } } diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java new file mode 100644 index 0000000..1614ec5 --- /dev/null +++ b/graphics/java/android/renderscript/Program.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + + +import android.util.Config; +import android.util.Log; + + +/** + * @hide + * + **/ +public class Program extends BaseObj { + public static final int MAX_INPUT = 8; + public static final int MAX_OUTPUT = 8; + public static final int MAX_CONSTANT = 8; + public static final int MAX_TEXTURE = 8; + + Element mInputs[]; + Element mOutputs[]; + Type mConstants[]; + int mTextureCount; + String mShader; + + Program(int id, RenderScript rs) { + super(rs); + mID = id; + } + + public void bindConstants(Allocation a, int slot) { + mRS.nProgramBindConstants(mID, slot, a.mID); + } + + public void bindTexture(Allocation va, int slot) + throws IllegalArgumentException { + mRS.validate(); + if((slot < 0) || (slot >= mTextureCount)) { + throw new IllegalArgumentException("Slot ID out of range."); + } + + mRS.nProgramBindTexture(mID, slot, va.mID); + } + + public void bindSampler(Sampler vs, int slot) + throws IllegalArgumentException { + mRS.validate(); + if((slot < 0) || (slot >= mTextureCount)) { + throw new IllegalArgumentException("Slot ID out of range."); + } + + mRS.nProgramBindSampler(mID, slot, vs.mID); + } + + + public static class BaseProgramBuilder { + RenderScript mRS; + Element mInputs[]; + Element mOutputs[]; + Type mConstants[]; + Type mTextures[]; + int mInputCount; + int mOutputCount; + int mConstantCount; + int mTextureCount; + String mShader; + + + protected BaseProgramBuilder(RenderScript rs) { + mRS = rs; + mInputs = new Element[MAX_INPUT]; + mOutputs = new Element[MAX_OUTPUT]; + mConstants = new Type[MAX_CONSTANT]; + mInputCount = 0; + mOutputCount = 0; + mConstantCount = 0; + mTextureCount = 0; + } + + public void setShader(String s) { + mShader = s; + } + + public void addInput(Element e) throws IllegalStateException { + // Should check for consistant and non-conflicting names... + if(mInputCount >= MAX_INPUT) { + throw new IllegalArgumentException("Max input count exceeded."); + } + mInputs[mInputCount++] = e; + } + + public void addOutput(Element e) throws IllegalStateException { + // Should check for consistant and non-conflicting names... + if(mOutputCount >= MAX_OUTPUT) { + throw new IllegalArgumentException("Max output count exceeded."); + } + mOutputs[mOutputCount++] = e; + } + + public int addConstant(Type t) throws IllegalStateException { + // Should check for consistant and non-conflicting names... + if(mConstantCount >= MAX_CONSTANT) { + throw new IllegalArgumentException("Max input count exceeded."); + } + mConstants[mConstantCount] = t; + return mConstantCount++; + } + + public void setTextureCount(int count) throws IllegalArgumentException { + // Should check for consistant and non-conflicting names... + if(count >= MAX_CONSTANT) { + throw new IllegalArgumentException("Max texture count exceeded."); + } + mTextureCount = count; + } + + protected void initProgram(Program p) { + p.mInputs = new Element[mInputCount]; + System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount); + p.mOutputs = new Element[mOutputCount]; + System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount); + p.mConstants = new Type[mConstantCount]; + System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount); + p.mTextureCount = mTextureCount; + } + } + +} + + diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java index 1a72578..5e04f0c 100644 --- a/graphics/java/android/renderscript/ProgramFragment.java +++ b/graphics/java/android/renderscript/ProgramFragment.java @@ -25,134 +25,115 @@ import android.util.Log; * @hide * **/ -public class ProgramFragment extends BaseObj { - public static final int MAX_SLOT = 2; - - public enum EnvMode { - REPLACE (0), - MODULATE (1), - DECAL (2); - - int mID; - EnvMode(int id) { - mID = id; - } - } - - +public class ProgramFragment extends Program { ProgramFragment(int id, RenderScript rs) { - super(rs); - mID = id; + super(id, rs); } - public void bindTexture(Allocation va, int slot) - throws IllegalArgumentException { - mRS.validate(); - if((slot < 0) || (slot >= MAX_SLOT)) { - throw new IllegalArgumentException("Slot ID out of range."); + public static class ShaderBuilder extends BaseProgramBuilder { + public ShaderBuilder(RenderScript rs) { + super(rs); } - mRS.nProgramFragmentBindTexture(mID, slot, va.mID); - } + public ProgramFragment create() { + mRS.validate(); + int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + 1) * 2]; + int idx = 0; - public void bindSampler(Sampler vs, int slot) - throws IllegalArgumentException { - mRS.validate(); - if((slot < 0) || (slot >= MAX_SLOT)) { - throw new IllegalArgumentException("Slot ID out of range."); - } + for (int i=0; i < mInputCount; i++) { + tmp[idx++] = 0; + tmp[idx++] = mInputs[i].mID; + } + for (int i=0; i < mOutputCount; i++) { + tmp[idx++] = 1; + tmp[idx++] = mOutputs[i].mID; + } + for (int i=0; i < mConstantCount; i++) { + tmp[idx++] = 2; + tmp[idx++] = mConstants[i].mID; + } + tmp[idx++] = 3; + tmp[idx++] = mTextureCount; - mRS.nProgramFragmentBindSampler(mID, slot, vs.mID); + int id = mRS.nProgramFragmentCreate2(mShader, tmp); + ProgramFragment pf = new ProgramFragment(id, mRS); + initProgram(pf); + return pf; + } } - public static class Builder { + public static final int MAX_TEXTURE = 2; RenderScript mRS; - Element mIn; - Element mOut; boolean mPointSpriteEnable; - private class Slot { - Type mType; - EnvMode mEnv; - boolean mTexEnable; + public enum EnvMode { + REPLACE (1), + MODULATE (2), + DECAL (3); - Slot() { - mTexEnable = false; + int mID; + EnvMode(int id) { + mID = id; } } - Slot[] mSlots; - public Builder(RenderScript rs, Element in, Element out) { - mRS = rs; - mIn = in; - mOut = out; - mSlots = new Slot[MAX_SLOT]; - mPointSpriteEnable = false; - for(int ct=0; ct < MAX_SLOT; ct++) { - mSlots[ct] = new Slot(); - } - } + public enum Format { + ALPHA (1), + LUMINANCE_ALPHA (2), + RGB (3), + RGBA (4); - public void setType(int slot, Type t) - throws IllegalArgumentException { - if((slot < 0) || (slot >= MAX_SLOT)) { - throw new IllegalArgumentException("Slot ID out of range."); + int mID; + Format(int id) { + mID = id; } - - mSlots[slot].mType = t; } - public void setTexEnable(boolean enable, int slot) - throws IllegalArgumentException { - if((slot < 0) || (slot >= MAX_SLOT)) { - throw new IllegalArgumentException("Slot ID out of range."); + private class Slot { + EnvMode env; + Format format; + Slot(EnvMode _env, Format _fmt) { + env = _env; + format = _fmt; } + } + Slot[] mSlots; - mSlots[slot].mTexEnable = enable; + public Builder(RenderScript rs) { + mRS = rs; + mSlots = new Slot[MAX_TEXTURE]; + mPointSpriteEnable = false; } - public void setTexEnvMode(EnvMode env, int slot) + public void setTexture(EnvMode env, Format fmt, int slot) throws IllegalArgumentException { - if((slot < 0) || (slot >= MAX_SLOT)) { - throw new IllegalArgumentException("Slot ID out of range."); + if((slot < 0) || (slot >= MAX_TEXTURE)) { + throw new IllegalArgumentException("MAX_TEXTURE exceeded."); } - - mSlots[slot].mEnv = env; + mSlots[slot] = new Slot(env, fmt); } public void setPointSpriteTexCoordinateReplacement(boolean enable) { mPointSpriteEnable = enable; } - static synchronized ProgramFragment internalCreate(RenderScript rs, Builder b) { - int inID = 0; - int outID = 0; - if (b.mIn != null) { - inID = b.mIn.mID; - } - if (b.mOut != null) { - outID = b.mOut.mID; - } - rs.nProgramFragmentBegin(inID, outID, b.mPointSpriteEnable); - for(int ct=0; ct < MAX_SLOT; ct++) { - if(b.mSlots[ct].mTexEnable) { - Slot s = b.mSlots[ct]; - int typeID = 0; - if(s.mType != null) { - typeID = s.mType.mID; - } - rs.nProgramFragmentSetSlot(ct, true, s.mEnv.mID, typeID); - } - } - - int id = rs.nProgramFragmentCreate(); - return new ProgramFragment(id, rs); - } - public ProgramFragment create() { mRS.validate(); - return internalCreate(mRS, this); + int[] tmp = new int[MAX_TEXTURE * 2 + 1]; + if (mSlots[0] != null) { + tmp[0] = mSlots[0].env.mID; + tmp[1] = mSlots[0].format.mID; + } + if (mSlots[1] != null) { + tmp[2] = mSlots[1].env.mID; + tmp[3] = mSlots[1].format.mID; + } + tmp[4] = mPointSpriteEnable ? 1 : 0; + int id = mRS.nProgramFragmentCreate(tmp); + ProgramFragment pf = new ProgramFragment(id, mRS); + pf.mTextureCount = MAX_TEXTURE; + return pf; } } } diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java index ba97d5b..84f6f2d 100644 --- a/graphics/java/android/renderscript/ProgramVertex.java +++ b/graphics/java/android/renderscript/ProgramVertex.java @@ -25,72 +25,67 @@ import android.util.Log; * @hide * **/ -public class ProgramVertex extends BaseObj { +public class ProgramVertex extends Program { public static final int MAX_LIGHT = 8; + ProgramVertex(int id, RenderScript rs) { - super(rs); - mID = id; + super(id, rs); } public void bindAllocation(MatrixAllocation va) { mRS.validate(); - mRS.nProgramVertexBindAllocation(mID, va.mAlloc.mID); + bindConstants(va.mAlloc, 0); } public static class Builder { RenderScript mRS; - Element mIn; - Element mOut; - Light[] mLights; - int mLightCount; boolean mTextureMatrixEnable; - public Builder(RenderScript rs, Element in, Element out) { mRS = rs; - mIn = in; - mOut = out; - mLights = new Light[MAX_LIGHT]; - mLightCount = 0; } public void setTextureMatrixEnable(boolean enable) { mTextureMatrixEnable = enable; } - public void addLight(Light l) throws IllegalStateException { - if(mLightCount >= MAX_LIGHT) { - throw new IllegalArgumentException("Max light count exceeded."); - } - mLights[mLightCount] = l; - mLightCount++; + public ProgramVertex create() { + int id = mRS.nProgramVertexCreate(mTextureMatrixEnable); + return new ProgramVertex(id, mRS); } + } + public static class ShaderBuilder extends BaseProgramBuilder { + public ShaderBuilder(RenderScript rs) { + super(rs); + } + public ProgramVertex create() { + mRS.validate(); + int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount +1) * 2]; + int idx = 0; - static synchronized ProgramVertex internalCreate(RenderScript rs, Builder b) { - int inID = 0; - int outID = 0; - if (b.mIn != null) { - inID = b.mIn.mID; + for (int i=0; i < mInputCount; i++) { + tmp[idx++] = 0; + tmp[idx++] = mInputs[i].mID; } - if (b.mOut != null) { - outID = b.mOut.mID; + for (int i=0; i < mOutputCount; i++) { + tmp[idx++] = 1; + tmp[idx++] = mOutputs[i].mID; } - rs.nProgramVertexBegin(inID, outID); - for(int ct=0; ct < b.mLightCount; ct++) { - rs.nProgramVertexAddLight(b.mLights[ct].mID); + for (int i=0; i < mConstantCount; i++) { + tmp[idx++] = 2; + tmp[idx++] = mConstants[i].mID; } - rs.nProgramVertexSetTextureMatrixEnable(b.mTextureMatrixEnable); - int id = rs.nProgramVertexCreate(); - return new ProgramVertex(id, rs); - } + tmp[idx++] = 3; + tmp[idx++] = mTextureCount; - public ProgramVertex create() { - mRS.validate(); - return internalCreate(mRS, this); + int id = mRS.nProgramVertexCreate2(mShader, tmp); + ProgramVertex pv = new ProgramVertex(id, mRS); + initProgram(pv); + return pv; } } @@ -112,7 +107,7 @@ public class ProgramVertex extends BaseObj { mProjection = new Matrix(); mTexture = new Matrix(); - mAlloc = Allocation.createSized(rs, Element.USER_F32(rs), 48); + mAlloc = Allocation.createSized(rs, Element.createUser(rs, Element.DataType.FLOAT_32), 48); mAlloc.subData1D(MODELVIEW_OFFSET, 16, mModel.mMat); mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat); mAlloc.subData1D(TEXTURE_OFFSET, 16, mTexture.mMat); diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java index 0d8b675..29361af 100644 --- a/graphics/java/android/renderscript/RenderScript.java +++ b/graphics/java/android/renderscript/RenderScript.java @@ -76,8 +76,6 @@ public class RenderScript { native void nContextBindProgramFragment(int pf); native void nContextBindProgramVertex(int pf); native void nContextBindProgramRaster(int pr); - native void nContextAddDefineI32(String name, int value); - native void nContextAddDefineF(String name, float value); native void nContextPause(); native void nContextResume(); native int nContextGetMessage(int[] data, boolean wait); @@ -89,9 +87,9 @@ public class RenderScript { native void nObjDestroyOOB(int id); native int nFileOpen(byte[] name); - native void nElementBegin(); - native void nElementAdd(int kind, int type, boolean norm, int bits, String s); - native int nElementCreate(); + + native int nElementCreate(int type, int kind, boolean norm, int vecSize); + native int nElementCreate2(int[] elements, String[] names); native void nTypeBegin(int elementID); native void nTypeAdd(int dim, int val); @@ -167,17 +165,15 @@ public class RenderScript { native void nProgramRasterSetLineWidth(int pr, float v); native void nProgramRasterSetPointSize(int pr, float v); - native void nProgramFragmentBegin(int in, int out, boolean pointSpriteEnable); - native void nProgramFragmentBindTexture(int vpf, int slot, int a); - native void nProgramFragmentBindSampler(int vpf, int slot, int s); - native void nProgramFragmentSetSlot(int slot, boolean enable, int env, int vt); - native int nProgramFragmentCreate(); + native void nProgramBindConstants(int pv, int slot, int mID); + native void nProgramBindTexture(int vpf, int slot, int a); + native void nProgramBindSampler(int vpf, int slot, int s); + + native int nProgramFragmentCreate(int[] params); + native int nProgramFragmentCreate2(String shader, int[] params); - native void nProgramVertexBindAllocation(int pv, int mID); - native void nProgramVertexBegin(int inID, int outID); - native void nProgramVertexSetTextureMatrixEnable(boolean enable); - native void nProgramVertexAddLight(int id); - native int nProgramVertexCreate(); + native int nProgramVertexCreate(boolean texMat); + native int nProgramVertexCreate2(String shader, int[] params); native void nLightBegin(); native void nLightSetIsMono(boolean isMono); @@ -200,14 +196,13 @@ public class RenderScript { private Surface mSurface; private MessageThread mMessageThread; - Element mElement_USER_U8; Element mElement_USER_I8; Element mElement_USER_U16; Element mElement_USER_I16; Element mElement_USER_U32; Element mElement_USER_I32; - Element mElement_USER_FLOAT; + Element mElement_USER_F32; Element mElement_A_8; Element mElement_RGB_565; @@ -217,9 +212,12 @@ public class RenderScript { Element mElement_RGBA_8888; Element mElement_INDEX_16; - Element mElement_XY_F32; - Element mElement_XYZ_F32; - + Element mElement_POSITION_2; + Element mElement_POSITION_3; + Element mElement_TEXTURE_2; + Element mElement_NORMAL_3; + Element mElement_COLOR_U8_4; + Element mElement_COLOR_F32_4; /////////////////////////////////////////////////////////////////////////////////// // @@ -248,13 +246,8 @@ public class RenderScript { } } - void validateSurface() { - if (mSurface == null) { - throw new IllegalStateException("Uploading data to GL with no surface."); - } - } - public void contextSetPriority(Priority p) { + validate(); nContextSetPriority(p.mID); } @@ -305,23 +298,26 @@ public class RenderScript { nDeviceSetConfig(mDev, 0, 1); } mContext = nContextCreate(mDev, 0, useDepth); - Element.initPredefined(this); mMessageThread = new MessageThread(this); mMessageThread.start(); + Element.initPredefined(this); } public void contextSetSurface(int w, int h, Surface sur) { mSurface = sur; mWidth = w; mHeight = h; + validate(); nContextSetSurface(w, h, mSurface); } public void contextDump(int bits) { + validate(); nContextDump(bits); } public void destroy() { + validate(); nContextDeinitToClient(); mMessageThread.mRun = false; @@ -337,10 +333,12 @@ public class RenderScript { } void pause() { + validate(); nContextPause(); } void resume() { + validate(); nContextResume(); } @@ -381,22 +379,27 @@ public class RenderScript { } public void contextBindRootScript(Script s) { + validate(); nContextBindRootScript(safeID(s)); } public void contextBindProgramFragmentStore(ProgramStore p) { + validate(); nContextBindProgramFragmentStore(safeID(p)); } public void contextBindProgramFragment(ProgramFragment p) { + validate(); nContextBindProgramFragment(safeID(p)); } public void contextBindProgramRaster(ProgramRaster p) { + validate(); nContextBindProgramRaster(safeID(p)); } public void contextBindProgramVertex(ProgramVertex p) { + validate(); nContextBindProgramVertex(safeID(p)); } diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java index 625a576..40ba722 100644 --- a/graphics/java/android/renderscript/Sampler.java +++ b/graphics/java/android/renderscript/Sampler.java @@ -69,23 +69,45 @@ public class Sampler extends BaseObj { } public void setMin(Value v) { - mMin = v; + if (v == Value.NEAREST || + v == Value.LINEAR || + v == Value.LINEAR_MIP_LINEAR) { + mMin = v; + } else { + throw new IllegalArgumentException("Invalid value"); + } } public void setMag(Value v) { - mMag = v; + if (v == Value.NEAREST || v == Value.LINEAR) { + mMag = v; + } else { + throw new IllegalArgumentException("Invalid value"); + } } public void setWrapS(Value v) { - mWrapS = v; + if (v == Value.WRAP || v == Value.CLAMP) { + mWrapS = v; + } else { + throw new IllegalArgumentException("Invalid value"); + } } public void setWrapT(Value v) { - mWrapT = v; + if (v == Value.WRAP || v == Value.CLAMP) { + mWrapT = v; + } else { + throw new IllegalArgumentException("Invalid value"); + } } public void setWrapR(Value v) { - mWrapR = v; + if (v == Value.WRAP || v == Value.CLAMP) { + mWrapR = v; + } else { + throw new IllegalArgumentException("Invalid value"); + } } static synchronized Sampler internalCreate(RenderScript rs, Builder b) { diff --git a/graphics/java/android/renderscript/SimpleMesh.java b/graphics/java/android/renderscript/SimpleMesh.java index f45074e..4a217a9 100644 --- a/graphics/java/android/renderscript/SimpleMesh.java +++ b/graphics/java/android/renderscript/SimpleMesh.java @@ -313,28 +313,36 @@ public class SimpleMesh extends BaseObj { public SimpleMesh create() { Element.Builder b = new Element.Builder(mRS); int floatCount = mVtxSize; - if (mVtxSize == 2) { - b.addFloatXY(); - } else { - b.addFloatXYZ(); - } + b.add(Element.createAttrib(mRS, + Element.DataType.FLOAT_32, + Element.DataKind.POSITION, + mVtxSize), "position"); if ((mFlags & COLOR) != 0) { floatCount += 4; - b.addFloatRGBA(); + b.add(Element.createAttrib(mRS, + Element.DataType.FLOAT_32, + Element.DataKind.COLOR, + 4), "color"); } if ((mFlags & TEXTURE_0) != 0) { floatCount += 2; - b.addFloatST(); + b.add(Element.createAttrib(mRS, + Element.DataType.FLOAT_32, + Element.DataKind.TEXTURE, + 2), "texture"); } if ((mFlags & NORMAL) != 0) { floatCount += 3; - b.addFloatNorm(); + b.add(Element.createAttrib(mRS, + Element.DataType.FLOAT_32, + Element.DataKind.NORMAL, + 3), "normal"); } mElement = b.create(); Builder smb = new Builder(mRS); smb.addVertexType(mElement, mVtxCount / floatCount); - smb.setIndexType(Element.INDEX_16(mRS), mIndexCount); + smb.setIndexType(Element.createIndex(mRS), mIndexCount); smb.setPrimitive(Primitive.TRIANGLE); SimpleMesh sm = smb.create(); diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java index ad4cf6b..62d3867 100644 --- a/graphics/java/android/renderscript/Type.java +++ b/graphics/java/android/renderscript/Type.java @@ -34,6 +34,9 @@ public class Type extends BaseObj { private int mNativeCache; Class mJavaClass; + public Element getElement() { + return mElement; + } public int getX() { return mDimX; @@ -122,16 +125,16 @@ public class Type extends BaseObj { Field f = fields[ct]; Class fc = f.getType(); if(fc == int.class) { - arTypes[ct] = Element.DataType.SIGNED.mID; + arTypes[ct] = Element.DataType.SIGNED_32.mID; arBits[ct] = 32; } else if(fc == short.class) { - arTypes[ct] = Element.DataType.SIGNED.mID; + arTypes[ct] = Element.DataType.SIGNED_16.mID; arBits[ct] = 16; } else if(fc == byte.class) { - arTypes[ct] = Element.DataType.SIGNED.mID; + arTypes[ct] = Element.DataType.SIGNED_8.mID; arBits[ct] = 8; } else if(fc == float.class) { - arTypes[ct] = Element.DataType.FLOAT.mID; + arTypes[ct] = Element.DataType.FLOAT_32.mID; arBits[ct] = 32; } else { throw new IllegalArgumentException("Unkown field type"); diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp index af3bc74..7ded133 100644 --- a/graphics/jni/android_renderscript_RenderScript.cpp +++ b/graphics/jni/android_renderscript_RenderScript.cpp @@ -247,36 +247,39 @@ static void nContextDeinitToClient(JNIEnv *_env, jobject _this) } -static void -nElementBegin(JNIEnv *_env, jobject _this) +static jint +nElementCreate(JNIEnv *_env, jobject _this, jint type, jint kind, jboolean norm, jint size) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nElementBegin, con(%p)", con); - rsElementBegin(con); + LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", con, type, kind, norm, size); + return (jint)rsElementCreate(con, (RsDataType)type, (RsDataKind)kind, norm, size); } - -static void -nElementAdd(JNIEnv *_env, jobject _this, jint kind, jint type, jboolean norm, jint bits, jstring name) +static jint +nElementCreate2(JNIEnv *_env, jobject _this, jintArray _ids, jobjectArray _names) { + int fieldCount = _env->GetArrayLength(_ids); RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - const char* n = NULL; - if (name) { - n = _env->GetStringUTFChars(name, NULL); + LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", con, type, kind, norm, size); + + jint *ids = _env->GetIntArrayElements(_ids, NULL); + const char ** nameArray = (const char **)calloc(fieldCount, sizeof(char *)); + size_t* sizeArray = (size_t*)calloc(fieldCount, sizeof(size_t)); + + for (int ct=0; ct < fieldCount; ct++) { + jstring s = (jstring)_env->GetObjectArrayElement(_names, ct); + nameArray[ct] = _env->GetStringUTFChars(s, NULL); + sizeArray[ct] = _env->GetStringUTFLength(s); } - LOG_API("nElementAdd, con(%p), kind(%i), type(%i), norm(%i), bits(%i)", con, kind, type, norm, bits); - rsElementAdd(con, (RsDataKind)kind, (RsDataType)type, norm != 0, (size_t)bits, n); - if (n) { - _env->ReleaseStringUTFChars(name, n); + jint id = (jint)rsElementCreate2(con, fieldCount, (RsElement *)ids, nameArray, sizeArray); + for (int ct=0; ct < fieldCount; ct++) { + jstring s = (jstring)_env->GetObjectArrayElement(_names, ct); + _env->ReleaseStringUTFChars(s, nameArray[ct]); } -} - -static jint -nElementCreate(JNIEnv *_env, jobject _this) -{ - RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nElementCreate, con(%p)", con); - return (jint)rsElementCreate(con); + _env->ReleaseIntArrayElements(_ids, ids, JNI_ABORT); + free(nameArray); + free(sizeArray); + return (jint)id; } // ----------------------------------- @@ -395,26 +398,24 @@ nTypeSetupFields(JNIEnv *_env, jobject _this, jobject _type, jintArray _types, j tfc[ct].bits = fBits[ct]; switch(fType[ct]) { - case RS_TYPE_FLOAT: + case RS_TYPE_FLOAT_32: tfc[ct].ptr = SF_LoadFloat; tfc[ct].readPtr = SF_SaveFloat; break; - case RS_TYPE_UNSIGNED: - case RS_TYPE_SIGNED: - switch(tfc[ct].bits) { - case 32: - tfc[ct].ptr = SF_LoadInt; - tfc[ct].readPtr = SF_SaveInt; - break; - case 16: - tfc[ct].ptr = SF_LoadShort; - tfc[ct].readPtr = SF_SaveShort; - break; - case 8: - tfc[ct].ptr = SF_LoadByte; - tfc[ct].readPtr = SF_SaveByte; - break; - } + case RS_TYPE_UNSIGNED_32: + case RS_TYPE_SIGNED_32: + tfc[ct].ptr = SF_LoadInt; + tfc[ct].readPtr = SF_SaveInt; + break; + case RS_TYPE_UNSIGNED_16: + case RS_TYPE_SIGNED_16: + tfc[ct].ptr = SF_LoadShort; + tfc[ct].readPtr = SF_SaveShort; + break; + case RS_TYPE_UNSIGNED_8: + case RS_TYPE_SIGNED_8: + tfc[ct].ptr = SF_LoadByte; + tfc[ct].readPtr = SF_SaveByte; break; } tc->size += 4; @@ -1056,87 +1057,89 @@ nProgramFragmentStoreCreate(JNIEnv *_env, jobject _this) // --------------------------------------------------------------------------- static void -nProgramFragmentBegin(JNIEnv *_env, jobject _this, jint in, jint out, jboolean pointSpriteEnable) +nProgramBindConstants(JNIEnv *_env, jobject _this, jint vpv, jint slot, jint a) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramFragmentBegin, con(%p), in(%p), out(%p) PointSprite(%i)", con, (RsElement)in, (RsElement)out, pointSpriteEnable); - rsProgramFragmentBegin(con, (RsElement)in, (RsElement)out, pointSpriteEnable); + LOG_API("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a); + rsProgramBindConstants(con, (RsProgram)vpv, slot, (RsAllocation)a); } static void -nProgramFragmentBindTexture(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a) +nProgramBindTexture(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramFragmentBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a); - rsProgramFragmentBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a); + LOG_API("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a); + rsProgramBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a); } static void -nProgramFragmentBindSampler(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a) +nProgramBindSampler(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramFragmentBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a); - rsProgramFragmentBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a); + LOG_API("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a); + rsProgramBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a); } -static void -nProgramFragmentSetSlot(JNIEnv *_env, jobject _this, jint slot, jboolean enable, jint env, jint vt) -{ - RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramFragmentSetType, con(%p), slot(%i), enable(%i), env(%i), vt(%p)", con, slot, enable, env, (RsType)vt); - rsProgramFragmentSetSlot(con, slot, enable, (RsTexEnvMode)env, (RsType)vt); -} +// --------------------------------------------------------------------------- static jint -nProgramFragmentCreate(JNIEnv *_env, jobject _this, jint slot, jboolean enable) +nProgramFragmentCreate(JNIEnv *_env, jobject _this, jintArray params) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramFragmentCreate, con(%p)", con); - return (jint)rsProgramFragmentCreate(con); -} + jint *paramPtr = _env->GetIntArrayElements(params, NULL); + jint paramLen = _env->GetArrayLength(params); -// --------------------------------------------------------------------------- + LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", con, shaderLen, paramLen); -static void -nProgramVertexBegin(JNIEnv *_env, jobject _this, jint in, jint out) -{ - RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramVertexBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out); - rsProgramVertexBegin(con, (RsElement)in, (RsElement)out); + jint ret = (jint)rsProgramFragmentCreate(con, (uint32_t *)paramPtr, paramLen); + _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT); + return ret; } -static void -nProgramVertexBindAllocation(JNIEnv *_env, jobject _this, jint vpv, jint a) +static jint +nProgramFragmentCreate2(JNIEnv *_env, jobject _this, jstring shader, jintArray params) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramVertexBindAllocation, con(%p), vpf(%p), a(%p)", con, (RsProgramVertex)vpv, (RsAllocation)a); - rsProgramVertexBindAllocation(con, (RsProgramFragment)vpv, (RsAllocation)a); -} + const char* shaderUTF = _env->GetStringUTFChars(shader, NULL); + jint shaderLen = _env->GetStringUTFLength(shader); + jint *paramPtr = _env->GetIntArrayElements(params, NULL); + jint paramLen = _env->GetArrayLength(params); -static void -nProgramVertexSetTextureMatrixEnable(JNIEnv *_env, jobject _this, jboolean enable) -{ - RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramVertexSetTextureMatrixEnable, con(%p), enable(%i)", con, enable); - rsProgramVertexSetTextureMatrixEnable(con, enable); + LOG_API("nProgramFragmentCreate2, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen); + + jint ret = (jint)rsProgramFragmentCreate2(con, shaderUTF, shaderLen, (uint32_t *)paramPtr, paramLen); + _env->ReleaseStringUTFChars(shader, shaderUTF); + _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT); + return ret; } -static void -nProgramVertexAddLight(JNIEnv *_env, jobject _this, jint light) + +// --------------------------------------------------------------------------- + +static jint +nProgramVertexCreate(JNIEnv *_env, jobject _this, jboolean texMat) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramVertexAddLight, con(%p), light(%p)", con, (RsLight)light); - rsProgramVertexAddLight(con, (RsLight)light); + LOG_API("nProgramVertexCreate, con(%p), texMat(%i)", con, texMat); + return (jint)rsProgramVertexCreate(con, texMat); } static jint -nProgramVertexCreate(JNIEnv *_env, jobject _this) +nProgramVertexCreate2(JNIEnv *_env, jobject _this, jstring shader, jintArray params) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramVertexCreate, con(%p)", con); - return (jint)rsProgramVertexCreate(con); -} + const char* shaderUTF = _env->GetStringUTFChars(shader, NULL); + jint shaderLen = _env->GetStringUTFLength(shader); + jint *paramPtr = _env->GetIntArrayElements(params, NULL); + jint paramLen = _env->GetArrayLength(params); + + LOG_API("nProgramVertexCreate2, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen); + jint ret = (jint)rsProgramVertexCreate2(con, shaderUTF, shaderLen, (uint32_t *)paramPtr, paramLen); + _env->ReleaseStringUTFChars(shader, shaderUTF); + _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT); + return ret; +} // --------------------------------------------------------------------------- @@ -1209,26 +1212,6 @@ nContextBindProgramRaster(JNIEnv *_env, jobject _this, jint pf) rsContextBindProgramRaster(con, (RsProgramRaster)pf); } -static void -nContextAddDefineI32(JNIEnv *_env, jobject _this, jstring name, jint value) -{ - RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - const char* n = _env->GetStringUTFChars(name, NULL); - LOG_API("nScriptCAddDefineI32, con(%p) name(%s) value(%d)", con, n, value); - rsContextSetDefineI32(con, n, value); - _env->ReleaseStringUTFChars(name, n); -} - -static void -nContextAddDefineF(JNIEnv *_env, jobject _this, jstring name, jfloat value) -{ - RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - const char* n = _env->GetStringUTFChars(name, NULL); - LOG_API("nScriptCAddDefineF, con(%p) name(%s) value(%f)", con, n, value); - rsContextSetDefineF(con, n, value); - _env->ReleaseStringUTFChars(name, n); -} - // --------------------------------------------------------------------------- @@ -1365,9 +1348,8 @@ static JNINativeMethod methods[] = { {"nFileOpen", "([B)I", (void*)nFileOpen }, -{"nElementBegin", "()V", (void*)nElementBegin }, -{"nElementAdd", "(IIZILjava/lang/String;)V", (void*)nElementAdd }, -{"nElementCreate", "()I", (void*)nElementCreate }, +{"nElementCreate", "(IIZI)I", (void*)nElementCreate }, +{"nElementCreate2", "([I[Ljava/lang/String;)I", (void*)nElementCreate2 }, {"nTypeBegin", "(I)V", (void*)nTypeBegin }, {"nTypeAdd", "(II)V", (void*)nTypeAdd }, @@ -1432,21 +1414,19 @@ static JNINativeMethod methods[] = { {"nProgramFragmentStoreDither", "(Z)V", (void*)nProgramFragmentStoreDither }, {"nProgramFragmentStoreCreate", "()I", (void*)nProgramFragmentStoreCreate }, -{"nProgramFragmentBegin", "(IIZ)V", (void*)nProgramFragmentBegin }, -{"nProgramFragmentBindTexture", "(III)V", (void*)nProgramFragmentBindTexture }, -{"nProgramFragmentBindSampler", "(III)V", (void*)nProgramFragmentBindSampler }, -{"nProgramFragmentSetSlot", "(IZII)V", (void*)nProgramFragmentSetSlot }, -{"nProgramFragmentCreate", "()I", (void*)nProgramFragmentCreate }, +{"nProgramBindConstants", "(III)V", (void*)nProgramBindConstants }, +{"nProgramBindTexture", "(III)V", (void*)nProgramBindTexture }, +{"nProgramBindSampler", "(III)V", (void*)nProgramBindSampler }, + +{"nProgramFragmentCreate", "([I)I", (void*)nProgramFragmentCreate }, +{"nProgramFragmentCreate2", "(Ljava/lang/String;[I)I", (void*)nProgramFragmentCreate2 }, {"nProgramRasterCreate", "(IIZZZ)I", (void*)nProgramRasterCreate }, {"nProgramRasterSetPointSize", "(IF)V", (void*)nProgramRasterSetPointSize }, {"nProgramRasterSetLineWidth", "(IF)V", (void*)nProgramRasterSetLineWidth }, -{"nProgramVertexBindAllocation", "(II)V", (void*)nProgramVertexBindAllocation }, -{"nProgramVertexBegin", "(II)V", (void*)nProgramVertexBegin }, -{"nProgramVertexSetTextureMatrixEnable", "(Z)V", (void*)nProgramVertexSetTextureMatrixEnable }, -{"nProgramVertexAddLight", "(I)V", (void*)nProgramVertexAddLight }, -{"nProgramVertexCreate", "()I", (void*)nProgramVertexCreate }, +{"nProgramVertexCreate", "(Z)I", (void*)nProgramVertexCreate }, +{"nProgramVertexCreate2", "(Ljava/lang/String;[I)I", (void*)nProgramVertexCreate2 }, {"nLightBegin", "()V", (void*)nLightBegin }, {"nLightSetIsMono", "(Z)V", (void*)nLightSetIsMono }, diff --git a/include/binder/IInterface.h b/include/binder/IInterface.h index 273d922..5f9f69c 100644 --- a/include/binder/IInterface.h +++ b/include/binder/IInterface.h @@ -72,21 +72,24 @@ protected: // ---------------------------------------------------------------------- #define DECLARE_META_INTERFACE(INTERFACE) \ - static const String16 descriptor; \ - static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); \ - virtual const String16& getInterfaceDescriptor() const; \ + static const android::String16 descriptor; \ + static android::sp<I##INTERFACE> asInterface( \ + const android::sp<android::IBinder>& obj); \ + virtual const android::String16& getInterfaceDescriptor() const; \ I##INTERFACE(); \ virtual ~I##INTERFACE(); \ #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ - const String16 I##INTERFACE::descriptor(NAME); \ - const String16& I##INTERFACE::getInterfaceDescriptor() const { \ + const android::String16 I##INTERFACE::descriptor(NAME); \ + const android::String16& \ + I##INTERFACE::getInterfaceDescriptor() const { \ return I##INTERFACE::descriptor; \ } \ - sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) \ + android::sp<I##INTERFACE> I##INTERFACE::asInterface( \ + const android::sp<android::IBinder>& obj) \ { \ - sp<I##INTERFACE> intr; \ + android::sp<I##INTERFACE> intr; \ if (obj != NULL) { \ intr = static_cast<I##INTERFACE*>( \ obj->queryLocalInterface( \ diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h index 571e47b..e81d0f9 100644..100755 --- a/include/ui/KeycodeLabels.h +++ b/include/ui/KeycodeLabels.h @@ -114,6 +114,10 @@ static const KeycodeLabel KEYCODES[] = { { "MEDIA_REWIND", 89 }, { "MEDIA_FAST_FORWARD", 90 }, { "MUTE", 91 }, + { "PAGE_UP", 92 }, + { "PAGE_DOWN", 93 }, + { "PICTSYMBOLS", 94 }, + { "SWITCH_CHARSET", 95 }, // NOTE: If you add a new keycode here you must also add it to: // (enum KeyCode, in this file) @@ -218,7 +222,11 @@ typedef enum KeyCode { kKeyCodePreviousSong = 88, kKeyCodeRewind = 89, kKeyCodeForward = 90, - kKeyCodeMute = 91 + kKeyCodeMute = 91, + kKeyCodePageUp = 92, + kKeyCodePageDown = 93, + kKeyCodePictSymbols = 94, + kKeyCodeSwitchCharset = 95 } KeyCode; static const KeycodeLabel FLAGS[] = { diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk index d364277..88521f6 100644 --- a/libs/rs/Android.mk +++ b/libs/rs/Android.mk @@ -96,11 +96,14 @@ LOCAL_SRC_FILES:= \ rsScript.cpp \ rsScriptC.cpp \ rsScriptC_Lib.cpp \ + rsShaderCache.cpp \ rsSimpleMesh.cpp \ rsThreadIO.cpp \ - rsType.cpp + rsType.cpp \ + rsVertexArray.cpp -LOCAL_SHARED_LIBRARIES += libcutils libutils libEGL libGLESv1_CM libui libacc + +LOCAL_SHARED_LIBRARIES += libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libacc LOCAL_LDLIBS := -lpthread -ldl LOCAL_MODULE:= libRS LOCAL_MODULE_TAGS := optional diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h index 3ca8b15..6662333 100644 --- a/libs/rs/RenderScript.h +++ b/libs/rs/RenderScript.h @@ -36,11 +36,11 @@ typedef void * RsElement; typedef void * RsFile; typedef void * RsSampler; typedef void * RsScript; -typedef void * RsScriptBasicTemp; typedef void * RsSimpleMesh; typedef void * RsType; typedef void * RsLight; +typedef void * RsProgram; typedef void * RsProgramVertex; typedef void * RsProgramFragment; typedef void * RsProgramFragmentStore; @@ -64,34 +64,53 @@ void rsContextInitToClient(RsContext); void rsContextDeinitToClient(RsContext); #define RS_MAX_TEXTURE 2 +#define RS_MAX_ATTRIBS 16 enum RsDataType { - RS_TYPE_FLOAT, - RS_TYPE_UNSIGNED, - RS_TYPE_SIGNED + RS_TYPE_NONE, + RS_TYPE_FLOAT_16, + RS_TYPE_FLOAT_32, + RS_TYPE_FLOAT_64, + RS_TYPE_SIGNED_8, + RS_TYPE_SIGNED_16, + RS_TYPE_SIGNED_32, + RS_TYPE_SIGNED_64, + RS_TYPE_UNSIGNED_8, + RS_TYPE_UNSIGNED_16, + RS_TYPE_UNSIGNED_32, + RS_TYPE_UNSIGNED_64, + + RS_TYPE_UNSIGNED_5_6_5, + RS_TYPE_UNSIGNED_5_5_5_1, + RS_TYPE_UNSIGNED_4_4_4_4, + + RS_TYPE_ELEMENT, + RS_TYPE_TYPE, + RS_TYPE_ALLOCATION, + RS_TYPE_SAMPLER, + RS_TYPE_SCRIPT, + RS_TYPE_MESH, + RS_TYPE_PROGRAM_FRAGMENT, + RS_TYPE_PROGRAM_VERTEX, + RS_TYPE_PROGRAM_RASTER, + RS_TYPE_PROGRAM_STORE }; enum RsDataKind { RS_KIND_USER, - RS_KIND_RED, - RS_KIND_GREEN, - RS_KIND_BLUE, - RS_KIND_ALPHA, - RS_KIND_LUMINANCE, - RS_KIND_INTENSITY, - RS_KIND_X, - RS_KIND_Y, - RS_KIND_Z, - RS_KIND_W, - RS_KIND_S, - RS_KIND_T, - RS_KIND_Q, - RS_KIND_R, - RS_KIND_NX, - RS_KIND_NY, - RS_KIND_NZ, + RS_KIND_COLOR, + RS_KIND_POSITION, + RS_KIND_TEXTURE, + RS_KIND_NORMAL, RS_KIND_INDEX, - RS_KIND_POINT_SIZE + RS_KIND_POINT_SIZE, + + RS_KIND_PIXEL_L, + RS_KIND_PIXEL_A, + RS_KIND_PIXEL_LA, + RS_KIND_PIXEL_RGB, + RS_KIND_PIXEL_RGBA, + }; enum RsSamplerParam { @@ -158,11 +177,19 @@ enum RsBlendDstFunc { }; enum RsTexEnvMode { + RS_TEX_ENV_MODE_NONE, RS_TEX_ENV_MODE_REPLACE, RS_TEX_ENV_MODE_MODULATE, RS_TEX_ENV_MODE_DECAL }; +enum RsProgramParam { + RS_PROGRAM_PARAM_INPUT, + RS_PROGRAM_PARAM_OUTPUT, + RS_PROGRAM_PARAM_CONSTANT, + RS_PROGRAM_PARAM_TEXTURE_COUNT, +}; + enum RsPrimitive { RS_PRIMITIVE_POINT, RS_PRIMITIVE_LINE, diff --git a/libs/rs/RenderScriptEnv.h b/libs/rs/RenderScriptEnv.h index ff0a7b1..99b8c04 100644 --- a/libs/rs/RenderScriptEnv.h +++ b/libs/rs/RenderScriptEnv.h @@ -9,7 +9,6 @@ typedef void * RsDevice; typedef void * RsElement; typedef void * RsSampler; typedef void * RsScript; -typedef void * RsScriptBasicTemp; typedef void * RsSimpleMesh; typedef void * RsType; typedef void * RsProgramFragment; diff --git a/libs/rs/java/Film/src/com/android/film/FilmRS.java b/libs/rs/java/Film/src/com/android/film/FilmRS.java index b5b6723..b80e619 100644 --- a/libs/rs/java/Film/src/com/android/film/FilmRS.java +++ b/libs/rs/java/Film/src/com/android/film/FilmRS.java @@ -121,13 +121,13 @@ public class FilmRS { bs.setWrapT(Sampler.Value.WRAP); mSampler = bs.create(); - ProgramFragment.Builder b = new ProgramFragment.Builder(mRS, null, null); - + ProgramFragment.Builder b = new ProgramFragment.Builder(mRS); mPFBackground = b.create(); mPFBackground.setName("PFBackground"); - b.setTexEnable(true, 0); - b.setTexEnvMode(ProgramFragment.EnvMode.REPLACE, 0); + b = new ProgramFragment.Builder(mRS); + b.setTexture(ProgramFragment.Builder.EnvMode.REPLACE, + ProgramFragment.Builder.Format.RGBA, 0); mPFImages = b.create(); mPFImages.bindSampler(mSampler, 0); mPFImages.setName("PFImages"); @@ -138,7 +138,7 @@ public class FilmRS { mLight.setPosition(0, -0.5f, -1.0f); ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null); - pvb.addLight(mLight); + //pvb.addLight(mLight); mPVBackground = pvb.create(); mPVBackground.setName("PVBackground"); @@ -152,9 +152,10 @@ public class FilmRS { mBufferIDs = new int[13]; mImages = new Allocation[13]; mAllocIDs = Allocation.createSized(mRS, - Element.USER_F32(mRS), mBufferIDs.length); + Element.createUser(mRS, Element.DataType.FLOAT_32), + mBufferIDs.length); - Element ie = Element.RGB_565(mRS); + Element ie = Element.createPixel(mRS, Element.DataType.UNSIGNED_5_6_5, Element.DataKind.PIXEL_RGB); mImages[0] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p01, ie, true); mImages[1] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p02, ie, true); mImages[2] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p03, ie, true); @@ -195,7 +196,8 @@ public class FilmRS { { mBufferState = new int[10]; mAllocState = Allocation.createSized(mRS, - Element.USER_F32(mRS), mBufferState.length); + Element.createUser(mRS, Element.DataType.FLOAT_32), + mBufferState.length); mBufferState[STATE_LAST_FOCUS] = -1; mAllocState.data(mBufferState); } @@ -238,12 +240,12 @@ public class FilmRS { mAllocOffsets = Allocation.createSized(mRS, - Element.USER_I32(mRS), mFSM.mTriangleOffsets.length); + Element.createUser(mRS, Element.DataType.SIGNED_32), mFSM.mTriangleOffsets.length); mAllocOffsets.data(mFSM.mTriangleOffsets); mScriptStrip.bindAllocation(mAllocOffsets, 4); mAllocOffsetsTex = Allocation.createSized(mRS, - Element.USER_F32(mRS), mFSM.mTriangleOffsetsTex.length); + Element.createUser(mRS, Element.DataType.FLOAT_32), mFSM.mTriangleOffsetsTex.length); mAllocOffsetsTex.data(mFSM.mTriangleOffsetsTex); mScriptStrip.bindAllocation(mAllocOffsetsTex, 5); diff --git a/libs/rs/java/Film/src/com/android/film/FilmView.java b/libs/rs/java/Film/src/com/android/film/FilmView.java index 1c5b2bc..4a201fd 100644 --- a/libs/rs/java/Film/src/com/android/film/FilmView.java +++ b/libs/rs/java/Film/src/com/android/film/FilmView.java @@ -42,19 +42,29 @@ public class FilmView extends RSSurfaceView { public FilmView(Context context) { super(context); - //setFocusable(true); } private RenderScript mRS; private FilmRS mRender; + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + mRS = createRenderScript(true); + mRS.contextSetSurface(w, h, holder.getSurface()); + mRender = new FilmRS(); + mRender.init(mRS, getResources(), w, h); + } + } - mRS = createRenderScript(true); - mRender = new FilmRS(); - mRender.init(mRS, getResources(), w, h); + @Override + protected void onDetachedFromWindow() { + if(mRS != null) { + mRS = null; + destroyRenderScript(); + } } @Override diff --git a/libs/rs/java/Fountain/res/raw/fountain.c b/libs/rs/java/Fountain/res/raw/fountain.c index f218f9b..73b819b 100644 --- a/libs/rs/java/Fountain/res/raw/fountain.c +++ b/libs/rs/java/Fountain/res/raw/fountain.c @@ -14,19 +14,17 @@ int main(int launchID) { float rMax = ((float)rate) * 0.005f; int x = Control->x; int y = Control->y; - char r = Control->r * 255.f; - char g = Control->g * 255.f; - char b = Control->b * 255.f; + int color = ((int)(Control->r * 255.f)) | + ((int)(Control->g * 255.f)) << 8 | + ((int)(Control->b * 255.f)) << 16 | + (0xf0 << 24); struct point_s * np = &p[newPart]; while (rate--) { - vec2Rand((float *)np, rMax); - np->x = x; - np->y = y; - np->r = r; - np->g = g; - np->b = b; - np->a = 0xf0; + vec2Rand((float *)&np->delta.x, rMax); + np->position.x = x; + np->position.y = y; + np->color = color; newPart++; np++; if (newPart >= count) { @@ -37,14 +35,14 @@ int main(int launchID) { } for (ct=0; ct < count; ct++) { - float dy = p->dy + 0.15f; - float posy = p->y + dy; + float dy = p->delta.y + 0.15f; + float posy = p->position.y + dy; if ((posy > height) && (dy > 0)) { dy *= -0.3f; } - p->dy = dy; - p->x += p->dx; - p->y = posy; + p->delta.y = dy; + p->position.x += p->delta.x; + p->position.y = posy; p++; } diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java index f4f9b0c..71f95a7 100644 --- a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java +++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java @@ -79,10 +79,9 @@ public class FountainRS { mIntAlloc.data(mSD); Element.Builder eb = new Element.Builder(mRS); - eb.addFloat(Element.DataKind.USER, "dx"); - eb.addFloat(Element.DataKind.USER, "dy"); - eb.addFloatXY(""); - eb.addUNorm8RGBA(""); + eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 2), "delta"); + eb.add(Element.createAttrib(mRS, Element.DataType.FLOAT_32, Element.DataKind.POSITION, 2), "position"); + eb.add(Element.createAttrib(mRS, Element.DataType.UNSIGNED_8, Element.DataKind.COLOR, 4), "color"); Element primElement = eb.create(); diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java index 1e7c5a2..fcb93f4 100644 --- a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java +++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java @@ -51,7 +51,7 @@ public class FountainView extends RSSurfaceView { public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { super.surfaceChanged(holder, format, w, h); if (mRS == null) { - mRS = createRenderScript(false, true); + mRS = createRenderScript(false); mRS.contextSetSurface(w, h, holder.getSurface()); mRender = new FountainRS(); mRender.init(mRS, getResources(), w, h); diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java index 334fd9c..0ca00b3 100644 --- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java @@ -62,7 +62,7 @@ public class ImageProcessingActivity extends Activity implements SurfaceHolder.C public float threshold; } - + static class Pixel { public byte a; public byte r; @@ -78,7 +78,7 @@ public class ImageProcessingActivity extends Activity implements SurfaceHolder.C mParams.outWidth, mParams.outHeight); mDisplayView.invalidate(); } - }; + }; @Override public void run() { @@ -131,7 +131,7 @@ public class ImageProcessingActivity extends Activity implements SurfaceHolder.C public void surfaceDestroyed(SurfaceHolder holder) { } - + private Script.Invokable createScript() { mRS = new RenderScript(false, false); mRS.mMessageCallback = new FilterCallback(); @@ -143,9 +143,11 @@ public class ImageProcessingActivity extends Activity implements SurfaceHolder.C final int pixelCount = mParams.inWidth * mParams.inHeight; mPixelType = Type.createFromClass(mRS, Pixel.class, 1, "Pixel"); - mInPixelsAllocation = Allocation.createSized(mRS, Element.USER_I32(mRS), + mInPixelsAllocation = Allocation.createSized(mRS, + Element.createUser(mRS, Element.DataType.SIGNED_32), pixelCount); - mOutPixelsAllocation = Allocation.createSized(mRS, Element.USER_I32(mRS), + mOutPixelsAllocation = Allocation.createSized(mRS, + Element.createUser(mRS, Element.DataType.SIGNED_32), pixelCount); final int[] data = new int[pixelCount]; @@ -154,7 +156,7 @@ public class ImageProcessingActivity extends Activity implements SurfaceHolder.C mOutData = new int[pixelCount]; mOutPixelsAllocation.data(mOutData); - + ScriptC.Builder sb = new ScriptC.Builder(mRS); sb.setType(mParamsType, "Params", 0); sb.setType(mPixelType, "InPixel", 1); diff --git a/libs/rs/java/Rollo/Android.mk b/libs/rs/java/Rollo/Android.mk deleted file mode 100644 index 5a4957c..0000000 --- a/libs/rs/java/Rollo/Android.mk +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-java-files-under, src) -#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript - -LOCAL_PACKAGE_NAME := Rollo - -include $(BUILD_PACKAGE) diff --git a/libs/rs/java/Rollo/AndroidManifest.xml b/libs/rs/java/Rollo/AndroidManifest.xml deleted file mode 100644 index 12cb28f..0000000 --- a/libs/rs/java/Rollo/AndroidManifest.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.rollo"> - <application - android:label="Rollo" - android:icon="@drawable/test_pattern"> - <activity android:name="Rollo" - android:theme="@android:style/Theme.Translucent" - android:icon="@drawable/test_pattern"> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> - </intent-filter> - </activity> - </application> -</manifest> diff --git a/libs/rs/java/Rollo/res/drawable/test_pattern.png b/libs/rs/java/Rollo/res/drawable/test_pattern.png Binary files differdeleted file mode 100644 index e7d1455..0000000 --- a/libs/rs/java/Rollo/res/drawable/test_pattern.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/browser.png b/libs/rs/java/Rollo/res/raw/browser.png Binary files differdeleted file mode 100644 index 513f0be..0000000 --- a/libs/rs/java/Rollo/res/raw/browser.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/calendar.png b/libs/rs/java/Rollo/res/raw/calendar.png Binary files differdeleted file mode 100644 index 030ae73..0000000 --- a/libs/rs/java/Rollo/res/raw/calendar.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/g1155.png b/libs/rs/java/Rollo/res/raw/g1155.png Binary files differdeleted file mode 100644 index 68e1843..0000000 --- a/libs/rs/java/Rollo/res/raw/g1155.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/g2140.png b/libs/rs/java/Rollo/res/raw/g2140.png Binary files differdeleted file mode 100644 index 8c4e853..0000000 --- a/libs/rs/java/Rollo/res/raw/g2140.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/maps.png b/libs/rs/java/Rollo/res/raw/maps.png Binary files differdeleted file mode 100644 index fd5fc39..0000000 --- a/libs/rs/java/Rollo/res/raw/maps.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/market.png b/libs/rs/java/Rollo/res/raw/market.png Binary files differdeleted file mode 100644 index 83b6910..0000000 --- a/libs/rs/java/Rollo/res/raw/market.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/path1920.png b/libs/rs/java/Rollo/res/raw/path1920.png Binary files differdeleted file mode 100644 index 3510665..0000000 --- a/libs/rs/java/Rollo/res/raw/path1920.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/path1927.png b/libs/rs/java/Rollo/res/raw/path1927.png Binary files differdeleted file mode 100644 index fccc846..0000000 --- a/libs/rs/java/Rollo/res/raw/path1927.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/path3099.png b/libs/rs/java/Rollo/res/raw/path3099.png Binary files differdeleted file mode 100644 index 527ebf6..0000000 --- a/libs/rs/java/Rollo/res/raw/path3099.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/path3950.png b/libs/rs/java/Rollo/res/raw/path3950.png Binary files differdeleted file mode 100644 index 59a646a..0000000 --- a/libs/rs/java/Rollo/res/raw/path3950.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/path431.png b/libs/rs/java/Rollo/res/raw/path431.png Binary files differdeleted file mode 100644 index 5d2ed75..0000000 --- a/libs/rs/java/Rollo/res/raw/path431.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/path4481.png b/libs/rs/java/Rollo/res/raw/path4481.png Binary files differdeleted file mode 100644 index 78be0fc..0000000 --- a/libs/rs/java/Rollo/res/raw/path4481.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/path5168.png b/libs/rs/java/Rollo/res/raw/path5168.png Binary files differdeleted file mode 100644 index a7c3a19..0000000 --- a/libs/rs/java/Rollo/res/raw/path5168.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/path676.png b/libs/rs/java/Rollo/res/raw/path676.png Binary files differdeleted file mode 100644 index 2099690..0000000 --- a/libs/rs/java/Rollo/res/raw/path676.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/path754.png b/libs/rs/java/Rollo/res/raw/path754.png Binary files differdeleted file mode 100644 index 88aed5b..0000000 --- a/libs/rs/java/Rollo/res/raw/path754.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/path815.png b/libs/rs/java/Rollo/res/raw/path815.png Binary files differdeleted file mode 100644 index 407570f..0000000 --- a/libs/rs/java/Rollo/res/raw/path815.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/photos.png b/libs/rs/java/Rollo/res/raw/photos.png Binary files differdeleted file mode 100644 index 1ed8f1e..0000000 --- a/libs/rs/java/Rollo/res/raw/photos.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/polygon2408.png b/libs/rs/java/Rollo/res/raw/polygon2408.png Binary files differdeleted file mode 100644 index 4413954..0000000 --- a/libs/rs/java/Rollo/res/raw/polygon2408.png +++ /dev/null diff --git a/libs/rs/java/Rollo/res/raw/rollo.c b/libs/rs/java/Rollo/res/raw/rollo.c deleted file mode 100644 index b31be81..0000000 --- a/libs/rs/java/Rollo/res/raw/rollo.c +++ /dev/null @@ -1,184 +0,0 @@ -#pragma version(1) -#pragma stateVertex(PV) -#pragma stateFragment(PF) -#pragma stateStore(PFS) - -// Scratch buffer layout -#define SCRATCH_FADE 0 -#define SCRATCH_ZOOM 1 -#define SCRATCH_ROT 2 - -//#define STATE_POS_X 0 -#define STATE_DONE 1 -//#define STATE_PRESSURE 2 -#define STATE_ZOOM 3 -//#define STATE_WARP 4 -#define STATE_ORIENTATION 5 -#define STATE_SELECTION 6 -#define STATE_FIRST_VISIBLE 7 -#define STATE_COUNT 8 -#define STATE_TOUCH 9 - - -float filter(float val, float target, float str) -{ - float delta = (target - val); - return val + delta * str; -} - -int main(void* con, int ft, int launchID) -{ - int rowCount; - int row; - int col; - int imageID; - int done = loadI32(0, STATE_DONE); - int selectedID = loadI32(0, STATE_SELECTION); - - float f = loadF(2, 0); - - pfClearColor(0.0f, 0.0f, 0.0f, f); - if (done) { - if (f > 0.02f) { - //f = f - 0.02f; - //storeF(2, 0, f); - } - } else { - if (f < 0.8f) { - f = f + 0.02f; - storeF(2, 0, f); - } - } - - float touchCut = 1.f; - if (loadI32(0, STATE_TOUCH)) { - touchCut = 4.f; - } - - - float targetZoom = ((float)loadI32(0, STATE_ZOOM)) / 1000.f; - float zoom = filter(loadF(2, SCRATCH_ZOOM), targetZoom, 0.15 * touchCut); - storeF(2, SCRATCH_ZOOM, zoom); - - float targetRot = loadI32(0, STATE_FIRST_VISIBLE) / 180.0f * 3.14f; - targetRot = targetRot * 0.80f - .12f; - float drawRot = filter(loadF(2, SCRATCH_ROT), targetRot, 0.1f * touchCut); - storeF(2, SCRATCH_ROT, drawRot); - - float diam = 8.f; - float scale = 1.0f / zoom; - - // Bug makes 1.0f alpha fail. - color(1.0f, 1.0f, 1.0f, 0.99f); - - float rot = drawRot * scale; - float rotStep = 16.0f / 180.0f * 3.14f * scale; - rowCount = 4; - int index = 0; - int iconCount = loadI32(0, STATE_COUNT); - while (iconCount) { - float tmpSin = sinf(rot); - float tmpCos = cosf(rot); - //debugF("rot", rot); - - float tx1 = tmpSin * diam - (tmpCos * scale * 0.9f); - float tx2 = tx1 + (tmpCos * scale * 1.8f); - float tz1 = tmpCos * diam + (tmpSin * scale * 0.9f); - float tz2 = tz1 - (tmpSin * scale * 1.8f); - - int y; - for (y = rowCount -1; (y >= 0) && iconCount; y--) { - float ty1 = ((y * 3.1f) - 5.f) * scale; - float ty2 = ty1 + scale * 1.8f; - bindTexture(NAMED_PF, 0, loadI32(1, index)); - drawQuad(tx1, ty1, tz1, - tx2, ty1, tz2, - tx2, ty2, tz2, - tx1, ty2, tz1); - - iconCount--; - index++; - } - rot = rot + rotStep; - } - - if ((zoom < 1.1f) && (zoom > 0.9f)) { - bindProgramVertex(NAMED_PVOrtho); - bindProgramFragment(NAMED_PFText); - bindProgramStore(NAMED_PFSText); - - rot = drawRot * scale; - index = 0; - iconCount = loadI32(0, STATE_COUNT); - while (iconCount) { - int y; - - float tx = 240.f + floorf(sinf(rot) * 430.f) - 64.f + 16.f; - - float alpha = 2.4f - (fabsf(tx - 240.f + 48.f) / 76.f); - if (alpha > 0.99f) { - alpha = 0.99f; - } - alpha = alpha * (1.f - (fabsf(zoom - 1.f) * 10.f)); - - tx = tx + 0.25f; - - for (y = rowCount -1; (y >= 0) && iconCount; y--) { - - if (alpha > 0) { - color(1.0f, 1.0f, 1.0f, alpha); - - float ty = 605.f - y * 150.f; - - ty = ty + 0.25f; - - bindTexture(NAMED_PFText, 0, loadI32(3, index)); - drawRect(tx, ty, tx + 128.f, ty + 32.f, 0.5f); - } - iconCount--; - index++; - } - rot = rot + rotStep; - } - - - bindProgramVertex(NAMED_PV); - bindProgramFragment(NAMED_PF); - bindProgramStore(NAMED_PFS); - } - - // Draw the selected icon - color(1.0f, 1.0f, 1.0f, 0.9f); - rot = drawRot * scale; - index = 0; - iconCount = loadI32(0, STATE_COUNT); - while (iconCount) { - int y; - for (y = rowCount -1; (y >= 0) && iconCount; y--) { - if (index == selectedID) { - - float tmpSin = sinf(rot) * scale; - float tmpCos = cosf(rot) * scale; - float tx1 = tmpSin * diam * 0.9f - tmpCos * 2.f; - float tx2 = tx1 + (tmpCos * 4.f); - float tz1 = tmpCos * diam * 0.9f + tmpSin * 2.f; - float tz2 = tz1 - (tmpSin * 4.f); - - float ty1 = ((y * 3.1f) - 4.5f) * scale; - float ty2 = ty1 + scale * 4.f; - bindTexture(NAMED_PF, 0, loadI32(1, index)); - drawQuad(tx1, ty1, tz1, - tx2, ty1, tz2, - tx2, ty2, tz2, - tx1, ty2, tz1); - } - iconCount--; - index++; - } - rot = rot + rotStep; - } - - return 1; -} - - diff --git a/libs/rs/java/Rollo/res/raw/rollo2.c b/libs/rs/java/Rollo/res/raw/rollo2.c deleted file mode 100644 index 5b5cb2d..0000000 --- a/libs/rs/java/Rollo/res/raw/rollo2.c +++ /dev/null @@ -1,155 +0,0 @@ -#pragma version(1) -#pragma stateVertex(PV) -#pragma stateFragment(PF) -#pragma stateStore(PFS) - -// Scratch buffer layout -#define SCRATCH_FADE 0 -#define SCRATCH_ZOOM 1 -#define SCRATCH_ROT 2 - -//#define STATE_POS_X 0 -#define STATE_DONE 1 -//#define STATE_PRESSURE 2 -#define STATE_ZOOM 3 -//#define STATE_WARP 4 -#define STATE_ORIENTATION 5 -#define STATE_SELECTION 6 -#define STATE_FIRST_VISIBLE 7 -#define STATE_COUNT 8 -#define STATE_TOUCH 9 - -float filter(float val, float target, float str) -{ - float delta = (target - val); - return val + delta * str; -} - - -int main(void* con, int ft, int launchID) -{ - int rowCount; - int imageID; - int done = loadI32(0, STATE_DONE); - int selectedID = loadI32(0, STATE_SELECTION); - int iconCount = loadI32(0, STATE_COUNT); - - float f = loadF(2, 0); - - float iconSize = 1.f; - float iconSpacing = 0.2f; - float z = 4.f; - - pfClearColor(0.0f, 0.0f, 0.0f, f); - if (done) { - } else { - if (f < 0.8f) { - f = f + 0.02f; - storeF(2, 0, f); - } - } - - float touchCut = 1.f; - if (loadI32(0, STATE_TOUCH)) { - touchCut = 5.f; - } - - - float targetZoom = ((float)loadI32(0, STATE_ZOOM)) / 1000.f; - float zoom = filter(loadF(2, SCRATCH_ZOOM), targetZoom, 0.15 * touchCut); - storeF(2, SCRATCH_ZOOM, zoom); - - float targetPos = loadI32(0, STATE_FIRST_VISIBLE) / (-20.0f); - float pos = filter(loadF(2, SCRATCH_ROT), targetPos, 0.1f * touchCut); - storeF(2, SCRATCH_ROT, pos); - pos = pos - 1.f; - - color(1.0f, 1.0f, 1.0f, 1.0f); - - - // Draw flat icons first - int index = ((int)pos) * 4; - int row; - int col; - float xoffset = -0.3f; - float gridSize = iconSize * 4.f + iconSpacing * 3.f; - float yoffset = (pos - ((int)pos)); - for (row = 0; row < 4; row ++) { - float ty1 = (gridSize / 2.f) - ((float)row - yoffset) * (iconSize + iconSpacing) - iconSize; - float ty2 = ty1 + iconSize; - - for (col = 0; (col < 4) && (index < iconCount); col ++) { - if (index >= 0) { - bindTexture(NAMED_PF, 0, loadI32(1, index)); - float fcol = col; - float tx1 = xoffset + (-gridSize / 2.f) + (fcol * (iconSize + iconSpacing)); - float tx2 = tx1 + iconSize; - - drawQuad(tx1, ty1, z, - tx2, ty1, z, - tx2, ty2, z, - tx1, ty2, z); - } - index++; - } - } - - // bottom roller - { - float roll = (1.f - yoffset) * 0.5f * 3.14f; - float tmpSin = sinf(roll); - float tmpCos = cosf(roll); - - for (col = 0; (col < 4) && (index < iconCount) && (index >= 0); col ++) { - float ty2 = (gridSize / 2.f) - ((float)row - yoffset) * (iconSize + iconSpacing); - float ty1 = ty2 - tmpCos * iconSize; - - float tz1 = z + tmpSin * iconSize; - float tz2 = z; - - float tx1 = xoffset + (-gridSize / 2.f) + ((float)col * (iconSize + iconSpacing)); - float tx2 = tx1 + iconSize; - - bindTexture(NAMED_PF, 0, loadI32(1, index)); - drawQuad(tx1, ty1, tz1, - tx2, ty1, tz1, - tx2, ty2, tz2, - tx1, ty2, tz2); - index++; - } - } - - // Top roller - { - index = (((int)pos) * 4) - 4; - float roll = yoffset * 0.5f * 3.14f; - float tmpSin = sinf(roll); - float tmpCos = cosf(roll); - - for (col = 0; (col < 4) && (index < iconCount) && (index >= 0); col ++) { - float ty1 = (gridSize / 2.f) - ((float)-1.f - yoffset) * (iconSize + iconSpacing) - iconSize; - float ty2 = ty1 + tmpCos * iconSize; - - float tz1 = z; - float tz2 = z + tmpSin * iconSize; - - float tx1 = xoffset + (-gridSize / 2.f) + ((float)col * (iconSize + iconSpacing)); - float tx2 = tx1 + iconSize; - - bindTexture(NAMED_PF, 0, loadI32(1, index)); - drawQuad(tx1, ty1, tz1, - tx2, ty1, tz1, - tx2, ty2, tz2, - tx1, ty2, tz2); - index++; - } - } - - - - - return 1; -} - - - diff --git a/libs/rs/java/Rollo/res/raw/settings.png b/libs/rs/java/Rollo/res/raw/settings.png Binary files differdeleted file mode 100644 index dd2cd95..0000000 --- a/libs/rs/java/Rollo/res/raw/settings.png +++ /dev/null diff --git a/libs/rs/java/Rollo/src/com/android/rollo/Rollo.java b/libs/rs/java/Rollo/src/com/android/rollo/Rollo.java deleted file mode 100644 index 400d801..0000000 --- a/libs/rs/java/Rollo/src/com/android/rollo/Rollo.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.rollo; - -import android.renderscript.RSSurfaceView; -import android.renderscript.RenderScript; - -import android.app.Activity; -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.Config; -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 java.lang.Runtime; - -public class Rollo extends Activity { - //EventListener mListener = new EventListener(); - - private static final String LOG_TAG = "libRS_jni"; - private static final boolean DEBUG = false; - private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; - - private RolloView mView; - - // get the current looper (from your Activity UI thread for instance - - - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - // Create our Preview view and set it as the content of our - // Activity - mView = new RolloView(this); - setContentView(mView); - } - - @Override - protected void onResume() { - // Ideally a game should implement onResume() and onPause() - // to take appropriate action when the activity looses focus - super.onResume(); - mView.onResume(); - } - - @Override - protected void onPause() { - // Ideally a game should implement onResume() and onPause() - // to take appropriate action when the activity looses focus - super.onPause(); - mView.onPause(); - - Runtime.getRuntime().exit(0); - } - - - static void log(String message) { - if (LOG_ENABLED) { - Log.v(LOG_TAG, message); - } - } - - -} - diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java deleted file mode 100644 index ff89bc3..0000000 --- a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.rollo; - -import java.io.Writer; - -import android.renderscript.RenderScript; -import android.renderscript.ProgramVertex; -import android.renderscript.Element; -import android.renderscript.Allocation; -import android.renderscript.Script; -import android.renderscript.ScriptC; -import android.renderscript.ProgramFragment; -import android.renderscript.ProgramStore; -import android.renderscript.Sampler; - -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.Typeface; - -import android.content.Context; -import android.content.res.Resources; -import android.util.Log; - -public class RolloRS { - //public static final int STATE_SELECTED_ID = 0; - public static final int STATE_DONE = 1; - //public static final int STATE_PRESSURE = 2; - public static final int STATE_ZOOM = 3; - //public static final int STATE_WARP = 4; - public static final int STATE_ORIENTATION = 5; - public static final int STATE_SELECTION = 6; - public static final int STATE_FIRST_VISIBLE = 7; - public static final int STATE_COUNT = 8; - public static final int STATE_TOUCH = 9; - - - public RolloRS() { - } - - public void init(RenderScript rs, Resources res, int width, int height) { - mRS = rs; - mRes = res; - mWidth = width; - mHeight = height; - initNamed(); - initRS(); - } - - public void setPosition(float column) { - mAllocStateBuf[STATE_FIRST_VISIBLE] = (int)(column * (-20)); - mAllocState.data(mAllocStateBuf); - } - - public void setTouch(boolean touch) { - mAllocStateBuf[STATE_TOUCH] = touch ? 1 : 0; - mAllocState.data(mAllocStateBuf); - } - - public void setZoom(float z) { - //Log.e("rs", "zoom " + Float.toString(z)); - - mAllocStateBuf[STATE_ZOOM] = (int)(z * 1000.f); - mAllocState.data(mAllocStateBuf); - } - - public void setSelected(int index) { - //Log.e("rs", "setSelected " + Integer.toString(index)); - - mAllocStateBuf[STATE_SELECTION] = index; - mAllocStateBuf[STATE_DONE] = 1; - mAllocState.data(mAllocStateBuf); - } - - private int mWidth; - private int mHeight; - - private Resources mRes; - private RenderScript mRS; - private Script mScript; - private Sampler mSampler; - private Sampler mSamplerText; - private ProgramStore mPSBackground; - private ProgramStore mPSText; - private ProgramFragment mPFImages; - private ProgramFragment mPFText; - private ProgramVertex mPV; - private ProgramVertex.MatrixAllocation mPVAlloc; - private ProgramVertex mPVOrtho; - private ProgramVertex.MatrixAllocation mPVOrthoAlloc; - private Allocation[] mIcons; - private Allocation[] mLabels; - - private int[] mAllocStateBuf; - private Allocation mAllocState; - - private int[] mAllocIconIDBuf; - private Allocation mAllocIconID; - - private int[] mAllocLabelIDBuf; - private Allocation mAllocLabelID; - - private int[] mAllocScratchBuf; - private Allocation mAllocScratch; - - private void initNamed() { - Sampler.Builder sb = new Sampler.Builder(mRS); - sb.setMin(Sampler.Value.LINEAR);//_MIP_LINEAR); - sb.setMag(Sampler.Value.LINEAR); - sb.setWrapS(Sampler.Value.CLAMP); - sb.setWrapT(Sampler.Value.CLAMP); - mSampler = sb.create(); - - sb.setMin(Sampler.Value.NEAREST); - sb.setMag(Sampler.Value.NEAREST); - mSamplerText = sb.create(); - - - ProgramFragment.Builder bf = new ProgramFragment.Builder(mRS, null, null); - bf.setTexEnable(true, 0); - bf.setTexEnvMode(ProgramFragment.EnvMode.MODULATE, 0); - mPFImages = bf.create(); - mPFImages.setName("PF"); - mPFImages.bindSampler(mSampler, 0); - - bf.setTexEnvMode(ProgramFragment.EnvMode.MODULATE, 0); - mPFText = bf.create(); - mPFText.setName("PFText"); - mPFText.bindSampler(mSamplerText, 0); - - ProgramStore.Builder bs = new ProgramStore.Builder(mRS, null, null); - bs.setDepthFunc(ProgramStore.DepthFunc.LESS); - bs.setDitherEnable(false); - bs.setDepthMask(true); - bs.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA, - ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA); - mPSBackground = bs.create(); - mPSBackground.setName("PFS"); - - bs.setDepthFunc(ProgramStore.DepthFunc.ALWAYS); - bs.setDepthMask(false); - bs.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA, - ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA); - mPSText = bs.create(); - mPSText.setName("PFSText"); - - mPVAlloc = new ProgramVertex.MatrixAllocation(mRS); - mPVAlloc.setupProjectionNormalized(mWidth, mHeight); - - ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null); - mPV = pvb.create(); - mPV.setName("PV"); - mPV.bindAllocation(mPVAlloc); - - mPVOrthoAlloc = new ProgramVertex.MatrixAllocation(mRS); - mPVOrthoAlloc.setupOrthoWindow(mWidth, mHeight); - - pvb.setTextureMatrixEnable(true); - mPVOrtho = pvb.create(); - mPVOrtho.setName("PVOrtho"); - mPVOrtho.bindAllocation(mPVOrthoAlloc); - - mRS.contextBindProgramVertex(mPV); - - mAllocScratchBuf = new int[32]; - mAllocScratch = Allocation.createSized(mRS, - Element.USER_I32(mRS), mAllocScratchBuf.length); - mAllocScratch.data(mAllocScratchBuf); - - Log.e("rs", "Done loading named"); - - - - { - mIcons = new Allocation[29]; - mAllocIconIDBuf = new int[mIcons.length]; - mAllocIconID = Allocation.createSized(mRS, - Element.USER_I32(mRS), mAllocIconIDBuf.length); - - mLabels = new Allocation[29]; - mAllocLabelIDBuf = new int[mLabels.length]; - mAllocLabelID = Allocation.createSized(mRS, - Element.USER_I32(mRS), mLabels.length); - - Element ie8888 = Element.RGBA_8888(mRS); - - mIcons[0] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.browser, ie8888, true); - mIcons[1] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.market, ie8888, true); - mIcons[2] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.photos, ie8888, true); - mIcons[3] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.settings, ie8888, true); - mIcons[4] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.calendar, ie8888, true); - mIcons[5] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.g1155, ie8888, true); - mIcons[6] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.g2140, ie8888, true); - mIcons[7] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.maps, ie8888, true); - mIcons[8] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path431, ie8888, true); - mIcons[9] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path676, ie8888, true); - mIcons[10] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path754, ie8888, true); - mIcons[11] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path815, ie8888, true); - mIcons[12] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path1920, ie8888, true); - mIcons[13] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path1927, ie8888, true); - mIcons[14] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path3099, ie8888, true); - mIcons[15] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path3950, ie8888, true); - mIcons[16] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path4481, ie8888, true); - mIcons[17] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path5168, ie8888, true); - mIcons[18] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.polygon2408, ie8888, true); - - mLabels[0] = makeTextBitmap("browser"); - mLabels[1] = makeTextBitmap("market"); - mLabels[2] = makeTextBitmap("photos"); - mLabels[3] = makeTextBitmap("settings"); - mLabels[4] = makeTextBitmap("calendar"); - mLabels[5] = makeTextBitmap("g1155"); - mLabels[6] = makeTextBitmap("g2140"); - mLabels[7] = makeTextBitmap("maps"); - mLabels[8] = makeTextBitmap("path431"); - mLabels[9] = makeTextBitmap("path676"); - mLabels[10] = makeTextBitmap("path754"); - mLabels[11] = makeTextBitmap("path815"); - mLabels[12] = makeTextBitmap("path1920"); - mLabels[13] = makeTextBitmap("path1927"); - mLabels[14] = makeTextBitmap("path3099"); - mLabels[15] = makeTextBitmap("path3950"); - mLabels[16] = makeTextBitmap("path4481"); - mLabels[17] = makeTextBitmap("path5168"); - mLabels[18] = makeTextBitmap("polygon2408"); - - mIcons[19] = mIcons[0]; - mIcons[20] = mIcons[1]; - mIcons[21] = mIcons[2]; - mIcons[22] = mIcons[3]; - mIcons[23] = mIcons[4]; - mIcons[24] = mIcons[5]; - mIcons[25] = mIcons[6]; - mIcons[26] = mIcons[7]; - mIcons[27] = mIcons[8]; - mIcons[28] = mIcons[9]; - - mLabels[19] = mLabels[0]; - mLabels[20] = mLabels[1]; - mLabels[21] = mLabels[2]; - mLabels[22] = mLabels[3]; - mLabels[23] = mLabels[4]; - mLabels[24] = mLabels[5]; - mLabels[25] = mLabels[6]; - mLabels[26] = mLabels[7]; - mLabels[27] = mLabels[8]; - mLabels[28] = mLabels[9]; - - for(int ct=0; ct < mIcons.length; ct++) { - mIcons[ct].uploadToTexture(0); - mLabels[ct].uploadToTexture(0); - mAllocIconIDBuf[ct] = mIcons[ct].getID(); - mAllocLabelIDBuf[ct] = mLabels[ct].getID(); - } - mAllocIconID.data(mAllocIconIDBuf); - mAllocLabelID.data(mAllocLabelIDBuf); - } - - } - - Allocation makeTextBitmap(String t) { - Bitmap b = Bitmap.createBitmap(128, 32, Bitmap.Config.ARGB_8888); - Canvas c = new Canvas(b); - Paint p = new Paint(); - p.setTypeface(Typeface.DEFAULT_BOLD); - p.setTextSize(20); - p.setColor(0xffffffff); - c.drawText(t, 2, 26, p); - return Allocation.createFromBitmap(mRS, b, Element.RGBA_8888(mRS), true); - } - - - private void initRS() { - ScriptC.Builder sb = new ScriptC.Builder(mRS); - sb.setScript(mRes, R.raw.rollo); - //sb.setScript(mRes, R.raw.rollo2); - sb.setRoot(true); - mScript = sb.create(); - mScript.setClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - mAllocStateBuf = new int[] {0, 0, 0, 8, 0, 0, -1, 0, mAllocIconIDBuf.length, 0, 0}; - mAllocState = Allocation.createSized(mRS, - Element.USER_I32(mRS), mAllocStateBuf.length); - mScript.bindAllocation(mAllocState, 0); - mScript.bindAllocation(mAllocIconID, 1); - mScript.bindAllocation(mAllocScratch, 2); - mScript.bindAllocation(mAllocLabelID, 3); - setPosition(0); - setZoom(1); - - //RenderScript.File f = mRS.fileOpen("/sdcard/test.a3d"); - - mRS.contextBindRootScript(mScript); - } -} - - diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java deleted file mode 100644 index 7524a0e..0000000 --- a/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.rollo; - -import java.io.Writer; -import java.util.ArrayList; -import java.util.concurrent.Semaphore; -import java.lang.Float; - -import android.renderscript.RSSurfaceView; -import android.renderscript.RenderScript; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.os.Handler; -import android.os.Message; -import android.util.AttributeSet; -import android.util.Log; -import android.view.Surface; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.graphics.PixelFormat; - - -public class RolloView extends RSSurfaceView { - public RolloView(Context context) { - super(context); - setFocusable(true); - getHolder().setFormat(PixelFormat.TRANSLUCENT); - } - - private RenderScript mRS; - private RolloRS mRender; - - public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { - super.surfaceChanged(holder, format, w, h); - - mRS = createRenderScript(false); - mRender = new RolloRS(); - mRender.init(mRS, getResources(), w, h); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) - { - // break point at here - // this method doesn't work when 'extends View' include 'extends ScrollView'. - return super.onKeyDown(keyCode, event); - } - - boolean mControlMode = false; - boolean mZoomMode = false; - boolean mFlingMode = false; - float mFlingX = 0; - float mFlingY = 0; - float mColumn = -1; - float mOldColumn; - float mZoom = 1; - - int mIconCount = 29; - int mRows = 4; - int mColumns = (mIconCount + mRows - 1) / mRows; - - float mMaxZoom = ((float)mColumns) / 3.f; - - - void setColumn(boolean clamp) - { - //Log.e("rs", " col = " + Float.toString(mColumn)); - float c = mColumn; - if(c > (mColumns -2)) { - c = (mColumns -2); - } - if(c < 0) { - c = 0; - } - mRender.setPosition(c); - if(clamp) { - mColumn = c; - } - } - - void computeSelection(float x, float y) - { - float col = mColumn + (x - 0.5f) * 4 + 1.25f; - int iCol = (int)(col + 0.25f); - - float row = (y / 0.8f) * mRows; - int iRow = (int)(row - 0.5f); - - mRender.setSelected(iCol * mRows + iRow); - } - - @Override - public boolean onTouchEvent(MotionEvent ev) - { - boolean ret = true; - int act = ev.getAction(); - if (act == ev.ACTION_UP) { - ret = false; - } - - float nx = ev.getX() / getWidth(); - float ny = ev.getY() / getHeight(); - - //Log.e("rs", "width=" + Float.toString(getWidth())); - //Log.e("rs", "height=" + Float.toString(getHeight())); - - mRender.setTouch(ret); - - if((ny > 0.85f) || mControlMode) { - mFlingMode = false; - - // Projector control - if((nx > 0.2f) && (nx < 0.8f) || mControlMode) { - if(act != ev.ACTION_UP) { - float zoom = mMaxZoom; - if(mControlMode) { - if(!mZoomMode) { - zoom = 1.f; - } - float dx = nx - mFlingX; - - if((ny < 0.9) && mZoomMode) { - zoom = mMaxZoom - ((0.9f - ny) * 10.f); - if(zoom < 1) { - zoom = 1; - mZoomMode = false; - } - mOldColumn = mColumn; - } - mColumn += dx * 4;// * zoom; - if(zoom > 1.01f) { - mColumn += (mZoom - zoom) * (nx - 0.5f) * 4 * zoom; - } - } else { - mOldColumn = mColumn; - mColumn = ((float)mColumns) / 2; - mControlMode = true; - mZoomMode = true; - } - mZoom = zoom; - mFlingX = nx; - mRender.setZoom(zoom); - if(mZoom < 1.01f) { - computeSelection(nx, ny); - } - } else { - mControlMode = false; - mColumn = mOldColumn; - mRender.setZoom(1.f); - mRender.setSelected(-1); - } - } else { - // Do something with corners here.... - } - setColumn(true); - - } else { - // icon control - if(act != ev.ACTION_UP) { - if(mFlingMode) { - mColumn += (mFlingX - nx) * 4; - setColumn(true); - } - mFlingMode = true; - mFlingX = nx; - mFlingY = ny; - } else { - mFlingMode = false; - mColumn = (float)(java.lang.Math.floor(mColumn * 0.25f + 0.3f) * 4.f) + 1.f; - setColumn(true); - } - } - - - return ret; - } - - @Override - public boolean onTrackballEvent(MotionEvent ev) - { - float x = ev.getX(); - float y = ev.getY(); - //Float tx = new Float(x); - //Float ty = new Float(y); - //Log.e("rs", "tbe " + tx.toString() + ", " + ty.toString()); - - - return true; - } - -} - - diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec index a4e72d9..ac115d3 100644 --- a/libs/rs/rs.spec +++ b/libs/rs/rs.spec @@ -20,16 +20,6 @@ ContextBindProgramRaster { param RsProgramRaster pgm } -ContextSetDefineF { - param const char* name - param float value - } - -ContextSetDefineI32 { - param const char* name - param int32_t value - } - ContextPause { } @@ -60,18 +50,19 @@ ObjDestroy { param void *obj } -ElementBegin { -} - -ElementAdd { - param RsDataKind dataKind - param RsDataType dataType - param bool isNormalized - param size_t bits - param const char * name +ElementCreate { + param RsDataType mType + param RsDataKind mKind + param bool mNormalized + param uint32_t mVectorSize + ret RsElement } -ElementCreate { +ElementCreate2 { + param size_t count + param const RsElement * elements + param const char ** names + param const size_t * nameLengths ret RsElement } @@ -366,56 +357,50 @@ ProgramRasterSetPointSize{ } -ProgramFragmentBegin { - param RsElement in - param RsElement out - param bool pointSpriteEnable +ProgramBindConstants { + param RsProgram vp + param uint32_t slot + param RsAllocation constants } -ProgramFragmentBindTexture { + +ProgramBindTexture { param RsProgramFragment pf param uint32_t slot param RsAllocation a } -ProgramFragmentBindSampler { +ProgramBindSampler { param RsProgramFragment pf param uint32_t slot param RsSampler s } -ProgramFragmentSetSlot { - param uint32_t slot - param bool enable - param RsTexEnvMode env - param RsType t - } - ProgramFragmentCreate { + param const uint32_t * params + param uint32_t paramLength ret RsProgramFragment } - -ProgramVertexBegin { - param RsElement in - param RsElement out +ProgramFragmentCreate2 { + param const char * shaderText + param uint32_t shaderLength + param const uint32_t * params + param uint32_t paramLength + ret RsProgramFragment } ProgramVertexCreate { + param bool texMat ret RsProgramVertex } -ProgramVertexBindAllocation { - param RsProgramVertex vpgm - param RsAllocation constants - } - -ProgramVertexSetTextureMatrixEnable { - param bool enable - } - -ProgramVertexAddLight { - param RsLight light +ProgramVertexCreate2 { + param const char * shaderText + param uint32_t shaderLength + param const uint32_t * params + param uint32_t paramLength + ret RsProgramVertex } LightBegin { diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index ff8d29f..eb6c503 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -38,9 +38,9 @@ Allocation::Allocation(Context *rsc, const Type *type) : ObjectBase(rsc) mIsTexture = false; mTextureID = 0; - mIsVertexBuffer = false; mBufferID = 0; + mUploadDefered = false; mType.set(type); rsAssert(type); @@ -88,13 +88,26 @@ bool Allocation::fixAllocation() return false; } -void Allocation::uploadToTexture(Context *rsc, uint32_t lodOffset) +void Allocation::deferedUploadToTexture(const Context *rsc, uint32_t lodOffset) { - //rsAssert(!mTextureId); rsAssert(lodOffset < mType->getLODCount()); + mIsTexture = true; + mTextureLOD = lodOffset; + mUploadDefered = true; +} + +void Allocation::uploadToTexture(const Context *rsc) +{ + //rsAssert(!mTextureId); + + mIsTexture = true; + if (!rsc->checkDriver()) { + mUploadDefered = true; + return; + } - GLenum type = mType->getElement()->getGLType(); - GLenum format = mType->getElement()->getGLFormat(); + GLenum type = mType->getElement()->getComponent().getGLType(); + GLenum format = mType->getElement()->getComponent().getGLFormat(); if (!type || !format) { return; @@ -109,15 +122,16 @@ void Allocation::uploadToTexture(Context *rsc, uint32_t lodOffset) // Force a crash to 1: restart the app, 2: make sure we get a bugreport. LOGE("Upload to texture failed to gen mTextureID"); rsc->dumpDebug(); - ((char *)0)[0] = 0; + mUploadDefered = true; + return; } } glBindTexture(GL_TEXTURE_2D, mTextureID); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); Adapter2D adapt(getContext(), this); - for(uint32_t lod = 0; (lod + lodOffset) < mType->getLODCount(); lod++) { - adapt.setLOD(lod+lodOffset); + for(uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) { + adapt.setLOD(lod+mTextureLOD); uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0)); glTexImage2D(GL_TEXTURE_2D, lod, format, @@ -126,19 +140,50 @@ void Allocation::uploadToTexture(Context *rsc, uint32_t lodOffset) } } -void Allocation::uploadToBufferObject() +void Allocation::deferedUploadToBufferObject(const Context *rsc) +{ + mIsVertexBuffer = true; + mUploadDefered = true; +} + +void Allocation::uploadToBufferObject(const Context *rsc) { rsAssert(!mType->getDimY()); rsAssert(!mType->getDimZ()); + mIsVertexBuffer = true; + if (!rsc->checkDriver()) { + mUploadDefered = true; + return; + } + if (!mBufferID) { glGenBuffers(1, &mBufferID); } + if (!mBufferID) { + LOGE("Upload to buffer object failed"); + mUploadDefered = true; + return; + } + glBindBuffer(GL_ARRAY_BUFFER, mBufferID); glBufferData(GL_ARRAY_BUFFER, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } +void Allocation::uploadCheck(const Context *rsc) +{ + if (mUploadDefered) { + mUploadDefered = false; + if (mIsVertexBuffer) { + uploadToBufferObject(rsc); + } + if (mIsTexture) { + uploadToTexture(rsc); + } + } +} + void Allocation::data(const void *data, uint32_t sizeBytes) { @@ -148,6 +193,8 @@ void Allocation::data(const void *data, uint32_t sizeBytes) return; } memcpy(mPtr, data, size); + sendDirty(); + mUploadDefered = true; } void Allocation::read(void *data) @@ -168,6 +215,8 @@ void Allocation::subData(uint32_t xoff, uint32_t count, const void *data, uint32 return; } memcpy(ptr, data, size); + sendDirty(); + mUploadDefered = true; } void Allocation::subData(uint32_t xoff, uint32_t yoff, @@ -192,6 +241,8 @@ void Allocation::subData(uint32_t xoff, uint32_t yoff, src += lineSize; dst += destW * eSize; } + sendDirty(); + mUploadDefered = true; } void Allocation::subData(uint32_t xoff, uint32_t yoff, uint32_t zoff, @@ -214,10 +265,30 @@ void Allocation::dumpLOGV(const char *prefix) const LOGV("%s allocation mIsTexture=%i mTextureID=%i, mIsVertexBuffer=%i, mBufferID=%i", prefix, mIsTexture, mTextureID, mIsVertexBuffer, mBufferID); +} +void Allocation::addProgramToDirty(const Program *p) +{ + mToDirtyList.add(p); +} +void Allocation::removeProgramToDirty(const Program *p) +{ + for (size_t ct=0; ct < mToDirtyList.size(); ct++) { + if (mToDirtyList[ct] == p) { + mToDirtyList.removeAt(ct); + return; + } + } + rsAssert(0); } +void Allocation::sendDirty() const +{ + for (size_t ct=0; ct < mToDirtyList.size(); ct++) { + mToDirtyList[ct]->forceDirty(); + } +} ///////////////// // @@ -247,13 +318,13 @@ RsAllocation rsi_AllocationCreateSized(Context *rsc, RsElement e, size_t count) void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, uint32_t baseMipLevel) { Allocation *alloc = static_cast<Allocation *>(va); - alloc->uploadToTexture(rsc, baseMipLevel); + alloc->deferedUploadToTexture(rsc, baseMipLevel); } void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) { Allocation *alloc = static_cast<Allocation *>(va); - alloc->uploadToBufferObject(); + alloc->deferedUploadToBufferObject(rsc); } static void mip565(const Adapter2D &out, const Adapter2D &in) @@ -294,6 +365,25 @@ static void mip8888(const Adapter2D &out, const Adapter2D &in) } } +static void mip8(const Adapter2D &out, const Adapter2D &in) +{ + uint32_t w = out.getDimX(); + uint32_t h = out.getDimY(); + + for (uint32_t y=0; y < h; y++) { + uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y)); + const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2)); + const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1)); + + for (uint32_t x=0; x < w; x++) { + *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f); + oPtr ++; + i1 += 2; + i2 += 2; + } + } +} + static void mip(const Adapter2D &out, const Adapter2D &in) { switch(out.getBaseType()->getElement()->getSizeBits()) { @@ -303,6 +393,9 @@ static void mip(const Adapter2D &out, const Adapter2D &in) case 16: mip565(out, in); break; + case 8: + mip8(out, in); + break; } @@ -350,10 +443,10 @@ static void elementConverter_8888_to_565(void *dst, const void *src, uint32_t co static ElementConverter_t pickConverter(const Element *dst, const Element *src) { - GLenum srcGLType = src->getGLType(); - GLenum srcGLFmt = src->getGLFormat(); - GLenum dstGLType = dst->getGLType(); - GLenum dstGLFmt = dst->getGLFormat(); + GLenum srcGLType = src->getComponent().getGLType(); + GLenum srcGLFmt = src->getComponent().getGLFormat(); + GLenum dstGLType = dst->getComponent().getGLType(); + GLenum dstGLFmt = dst->getComponent().getGLFormat(); if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) { switch(dst->getSizeBytes()) { @@ -391,8 +484,9 @@ RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h { const Element *src = static_cast<const Element *>(_src); const Element *dst = static_cast<const Element *>(_dst); - rsAssert(!(w & (w-1))); - rsAssert(!(h & (h-1))); + + // Check for pow2 on pre es 2.0 versions. + rsAssert(rsc->checkVersion2_0() || (!(w & (w-1)) && !(h & (h-1)))); //LOGE("rsi_AllocationCreateFromBitmap %i %i %i %i %i", w, h, dstFmt, srcFmt, genMips); rsi_TypeBegin(rsc, _dst); @@ -452,31 +546,24 @@ RsAllocation rsi_AllocationCreateFromBitmapBoxed(Context *rsc, uint32_t w, uint3 RsAllocation ret = rsi_AllocationCreateFromBitmap(rsc, w2, h2, _dst, _src, genMips, tmp); free(tmp); return ret; - - - - } void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes) { Allocation *a = static_cast<Allocation *>(va); a->data(data, sizeBytes); - rsc->allocationCheck(a); } void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) { Allocation *a = static_cast<Allocation *>(va); a->subData(xoff, count, data, sizeBytes); - rsc->allocationCheck(a); } void rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) { Allocation *a = static_cast<Allocation *>(va); a->subData(xoff, yoff, w, h, data, sizeBytes); - rsc->allocationCheck(a); } void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data) diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h index f54284a..f0b2122 100644 --- a/libs/rs/rsAllocation.h +++ b/libs/rs/rsAllocation.h @@ -23,7 +23,7 @@ namespace android { namespace renderscript { - +class Program; class Allocation : public ObjectBase { @@ -46,10 +46,12 @@ public: void * getPtr() const {return mPtr;} const Type * getType() const {return mType.get();} - void uploadToTexture(Context *rsc, uint32_t lodOffset = 0); + void deferedUploadToTexture(const Context *rsc, uint32_t lodOffset); + void uploadToTexture(const Context *rsc); uint32_t getTextureID() const {return mTextureID;} - void uploadToBufferObject(); + void deferedUploadToBufferObject(const Context *rsc); + void uploadToBufferObject(const Context *rsc); uint32_t getBufferObjectID() const {return mBufferID;} @@ -65,13 +67,21 @@ public: void enableGLVertexBuffers() const; void setupGLIndexBuffers() const; + void addProgramToDirty(const Program *); + void removeProgramToDirty(const Program *); + virtual void dumpLOGV(const char *prefix) const; + virtual void uploadCheck(const Context *rsc); protected: + void sendDirty() const; + ObjectBaseRef<const Type> mType; void * mPtr; + Vector<const Program *> mToDirtyList; + // Usage restrictions bool mCpuWrite; bool mCpuRead; @@ -88,6 +98,7 @@ protected: // Is this a legal structure to be used as a texture source. // Initially this will require 1D or 2D and color data bool mIsTexture; + uint32_t mTextureLOD; uint32_t mTextureID; // Is this a legal structure to be used as a vertex source. @@ -95,6 +106,8 @@ protected: // is allowed. bool mIsVertexBuffer; uint32_t mBufferID; + + bool mUploadDefered; }; } diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp index de074c8..15a56f7 100644 --- a/libs/rs/rsComponent.cpp +++ b/libs/rs/rsComponent.cpp @@ -15,96 +15,323 @@ */ #include "rsComponent.h" + #include <GLES/gl.h> using namespace android; using namespace android::renderscript; +Component::Component() +{ + set(RS_TYPE_NONE, RS_KIND_USER, false, 1); +} -Component::Component(Context *rsc) : ObjectBase(rsc) +Component::~Component() { - mAllocFile = __FILE__; - mAllocLine = __LINE__; - mType = FLOAT; - mKind = USER; - mIsNormalized = false; - mBits = 0; } -Component::Component(Context *rsc, - DataKind dk, DataType dt, - bool isNormalized, uint32_t bits, const char * name) : ObjectBase(rsc) +void Component::set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize) { - mAllocFile = __FILE__; - mAllocLine = __LINE__; mType = dt; mKind = dk; - mIsNormalized = isNormalized; - mBits = bits; - if (name) { - mName = name; + mNormalized = norm; + mVectorSize = vecSize; + rsAssert(vecSize <= 4); + + mBits = 0; + mTypeBits = 0; + mIsFloat = false; + mIsSigned = false; + mIsPixel = false; + + switch(mKind) { + case RS_KIND_PIXEL_L: + case RS_KIND_PIXEL_A: + mIsPixel = true; + rsAssert(mVectorSize == 1); + rsAssert(mNormalized == true); + break; + case RS_KIND_PIXEL_LA: + mIsPixel = true; + rsAssert(mVectorSize == 2); + rsAssert(mNormalized == true); + break; + case RS_KIND_PIXEL_RGB: + mIsPixel = true; + rsAssert(mVectorSize == 3); + rsAssert(mNormalized == true); + break; + case RS_KIND_PIXEL_RGBA: + mIsPixel = true; + rsAssert(mVectorSize == 4); + rsAssert(mNormalized == true); + break; + default: + break; } -} -const char * Component::getCType() const -{ switch(mType) { - case FLOAT: - return "float"; - case SIGNED: - case UNSIGNED: - switch(mBits) { - case 32: - return "int"; - case 16: - return "short"; - case 8: - return "char"; - } + case RS_TYPE_NONE: + return; + case RS_TYPE_UNSIGNED_5_6_5: + mVectorSize = 3; + mBits = 16; + mNormalized = true; + rsAssert(mKind == RS_KIND_PIXEL_RGB); + return; + case RS_TYPE_UNSIGNED_5_5_5_1: + mVectorSize = 4; + mBits = 16; + mNormalized = true; + rsAssert(mKind == RS_KIND_PIXEL_RGBA); + return; + case RS_TYPE_UNSIGNED_4_4_4_4: + mVectorSize = 4; + mBits = 16; + mNormalized = true; + rsAssert(mKind == RS_KIND_PIXEL_RGBA); + return; + case RS_TYPE_ELEMENT: + case RS_TYPE_TYPE: + case RS_TYPE_ALLOCATION: + case RS_TYPE_SAMPLER: + case RS_TYPE_SCRIPT: + case RS_TYPE_MESH: + case RS_TYPE_PROGRAM_FRAGMENT: + case RS_TYPE_PROGRAM_VERTEX: + case RS_TYPE_PROGRAM_RASTER: + case RS_TYPE_PROGRAM_STORE: + rsAssert(mVectorSize == 1); + rsAssert(mNormalized == false); + rsAssert(mKind == RS_KIND_USER); + mBits = 32; + mTypeBits = 32; + return; + + case RS_TYPE_FLOAT_16: + mTypeBits = 16; + mIsFloat = true; + break; + case RS_TYPE_FLOAT_32: + mTypeBits = 32; + mIsFloat = true; + break; + case RS_TYPE_FLOAT_64: + mTypeBits = 64; + mIsFloat = true; + break; + case RS_TYPE_SIGNED_8: + mTypeBits = 8; + mIsSigned = true; + break; + case RS_TYPE_SIGNED_16: + mTypeBits = 16; + mIsSigned = true; + break; + case RS_TYPE_SIGNED_32: + mTypeBits = 32; + mIsSigned = true; + break; + case RS_TYPE_SIGNED_64: + mTypeBits = 64; + mIsSigned = true; + break; + case RS_TYPE_UNSIGNED_8: + mTypeBits = 8; + break; + case RS_TYPE_UNSIGNED_16: + mTypeBits = 16; + break; + case RS_TYPE_UNSIGNED_32: + mTypeBits = 32; + break; + case RS_TYPE_UNSIGNED_64: + mTypeBits = 64; break; } - return NULL; + + mBits = mTypeBits * mVectorSize; } -Component::~Component() + + + +uint32_t Component::getGLType() const { + switch (mType) { + case RS_TYPE_UNSIGNED_5_6_5: return GL_UNSIGNED_SHORT_5_6_5; + case RS_TYPE_UNSIGNED_5_5_5_1: return GL_UNSIGNED_SHORT_5_5_5_1; + case RS_TYPE_UNSIGNED_4_4_4_4: return GL_UNSIGNED_SHORT_4_4_4_4; + + //case RS_TYPE_FLOAT_16: return GL_HALF_FLOAT; + case RS_TYPE_FLOAT_32: return GL_FLOAT; + case RS_TYPE_UNSIGNED_8: return GL_UNSIGNED_BYTE; + case RS_TYPE_UNSIGNED_16: return GL_UNSIGNED_SHORT; + case RS_TYPE_SIGNED_8: return GL_BYTE; + case RS_TYPE_SIGNED_16: return GL_SHORT; + default: break; + } + + return 0; } -uint32_t Component::getGLType() const +uint32_t Component::getGLFormat() const { - switch(mType) { - case RS_TYPE_FLOAT: - rsAssert(mBits == 32); - return GL_FLOAT; - case RS_TYPE_SIGNED: - switch(mBits) { - case 32: - return 0;//GL_INT; - case 16: - return GL_SHORT; - case 8: - return GL_BYTE; + switch (mKind) { + case RS_KIND_PIXEL_L: return GL_LUMINANCE; + case RS_KIND_PIXEL_A: return GL_ALPHA; + case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA; + case RS_KIND_PIXEL_RGB: return GL_RGB; + case RS_KIND_PIXEL_RGBA: return GL_RGBA; + default: break; + } + return 0; +} + +static const char * gCTypeStrings[] = { + 0, + 0,//"F16", + "float", + "double", + "char", + "short", + "int", + 0,//"S64", + "char",//U8", + "short",//U16", + "int",//U32", + 0,//"U64", + 0,//"UP_565", + 0,//"UP_5551", + 0,//"UP_4444", + 0,//"ELEMENT", + 0,//"TYPE", + 0,//"ALLOCATION", + 0,//"SAMPLER", + 0,//"SCRIPT", + 0,//"MESH", + 0,//"PROGRAM_FRAGMENT", + 0,//"PROGRAM_VERTEX", + 0,//"PROGRAM_RASTER", + 0,//"PROGRAM_STORE", +}; + +static const char * gCVecTypeStrings[] = { + 0, + 0,//"F16", + "vecF32", + "vecF64", + "vecI8", + "vecI16", + "vecI32", + 0,//"S64", + "vecU8",//U8", + "vecU16",//U16", + "vecU32",//U32", + 0,//"U64", + 0,//"UP_565", + 0,//"UP_5551", + 0,//"UP_4444", + 0,//"ELEMENT", + 0,//"TYPE", + 0,//"ALLOCATION", + 0,//"SAMPLER", + 0,//"SCRIPT", + 0,//"MESH", + 0,//"PROGRAM_FRAGMENT", + 0,//"PROGRAM_VERTEX", + 0,//"PROGRAM_RASTER", + 0,//"PROGRAM_STORE", +}; + +String8 Component::getCType() const +{ + char buf[64]; + if (mVectorSize == 1) { + return String8(gCTypeStrings[mType]); + } + + // Yuck, acc WAR + // Appears to have problems packing chars + if (mVectorSize == 4 && mType == RS_TYPE_UNSIGNED_8) { + return String8("int"); + } + + + String8 s(gCVecTypeStrings[mType]); + sprintf(buf, "_%i_t", mVectorSize); + s.append(buf); + return s; +} + +String8 Component::getGLSLType() const +{ + if (mType == RS_TYPE_SIGNED_32) { + switch(mVectorSize) { + case 1: return String8("int"); + case 2: return String8("ivec2"); + case 3: return String8("ivec3"); + case 4: return String8("ivec4"); } - break; - case RS_TYPE_UNSIGNED: - switch(mBits) { - case 32: - return 0;//GL_UNSIGNED_INT; - case 16: - return GL_UNSIGNED_SHORT; - case 8: - return GL_UNSIGNED_BYTE; + } + if (mType == RS_TYPE_FLOAT_32) { + switch(mVectorSize) { + case 1: return String8("float"); + case 2: return String8("vec2"); + case 3: return String8("vec3"); + case 4: return String8("vec4"); } - break; } - //rsAssert(!"Bad type"); - //LOGE("mType %i, mKind %i, mBits %i, mIsNormalized %i", mType, mKind, mBits, mIsNormalized); - return 0; + return String8(); } +static const char * gTypeStrings[] = { + "NONE", + "F16", + "F32", + "F64", + "S8", + "S16", + "S32", + "S64", + "U8", + "U16", + "U32", + "U64", + "UP_565", + "UP_5551", + "UP_4444", + "ELEMENT", + "TYPE", + "ALLOCATION", + "SAMPLER", + "SCRIPT", + "MESH", + "PROGRAM_FRAGMENT", + "PROGRAM_VERTEX", + "PROGRAM_RASTER", + "PROGRAM_STORE", +}; + +static const char * gKindStrings[] = { + "USER", + "COLOR", + "POSITION", + "TEXTURE", + "NORMAL", + "INDEX", + "POINT_SIZE", + "PIXEL_L", + "PIXEL_A", + "PIXEL_LA", + "PIXEL_RGB", + "PIXEL_RGBA", +}; + void Component::dumpLOGV(const char *prefix) const { - ObjectBase::dumpLOGV(prefix); - LOGV("%s component: %i %i %i %i", prefix, mType, mKind, mIsNormalized, mBits); + LOGV("%s Component: %s, %s, vectorSize=%i, bits=%i", + prefix, gTypeStrings[mType], gKindStrings[mKind], mVectorSize, mBits); } + diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h index 5366cc4..71de324 100644 --- a/libs/rs/rsComponent.h +++ b/libs/rs/rsComponent.h @@ -14,65 +14,56 @@ * limitations under the License. */ -#ifndef ANDROID_RS_STRUCTURED_COMPONENT_H -#define ANDROID_RS_STRUCTURED_COMPONENT_H +#ifndef ANDROID_COMPONENT_H +#define ANDROID_COMPONENT_H #include "rsUtils.h" -#include "rsObjectBase.h" // --------------------------------------------------------------------------- namespace android { namespace renderscript { -class Component : public ObjectBase + +// An element is a group of Components that occupies one cell in a structure. +class Component { public: - enum DataType { - FLOAT, - UNSIGNED, - SIGNED - }; - - enum DataKind { - USER, - RED, GREEN, BLUE, ALPHA, LUMINANCE, INTENSITY, - X, Y, Z, W, - S, T, Q, R, - NX, NY, NZ, - INDEX, - POINT_SIZE - }; - + Component(); + ~Component(); - Component(Context *rsc, DataKind dk, DataType dt, bool isNorm, uint32_t bits, const char *); - virtual ~Component(); - - DataType getType() const {return mType;} - bool getIsNormalized() const {return mIsNormalized;} - DataKind getKind() const {return mKind;} - uint32_t getBits() const {return mBits;} + void set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize=1); uint32_t getGLType() const; - const char * getCType() const; - - const char * getComponentName() const {return mName.string();} - virtual void dumpLOGV(const char *prefix) const; + uint32_t getGLFormat() const; + String8 getCType() const; + String8 getGLSLType() const; + void dumpLOGV(const char *prefix) const; + + + RsDataType getType() const {return mType;} + RsDataKind getKind() const {return mKind;} + bool getIsNormalized() const {return mNormalized;} + uint32_t getVectorSize() const {return mVectorSize;} + bool getIsFloat() const {return mIsFloat;} + bool getIsSigned() const {return mIsSigned;} + uint32_t getBits() const {return mBits;} protected: + RsDataType mType; + RsDataKind mKind; + bool mNormalized; + uint32_t mVectorSize; - DataType mType; - bool mIsNormalized; - DataKind mKind; + // derived uint32_t mBits; - String8 mName; - -private: - Component(Context *rsc); + uint32_t mTypeBits; + bool mIsFloat; + bool mIsSigned; + bool mIsPixel; }; - } } -#endif //ANDROID_RS_STRUCTURED_COMPONENT_H +#endif diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 3652f0a..261b827 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -27,6 +27,8 @@ #include <GLES/gl.h> #include <GLES/glext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> #include <cutils/sched_policy.h> @@ -50,11 +52,12 @@ static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { } } -void Context::initEGL() +void Context::initEGL(bool useGL2) { mEGL.mNumConfigs = -1; EGLint configAttribs[128]; EGLint *configAttribsPtr = configAttribs; + EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; memset(configAttribs, 0, sizeof(configAttribs)); @@ -62,6 +65,12 @@ void Context::initEGL() configAttribsPtr[1] = EGL_WINDOW_BIT; configAttribsPtr += 2; + if (useGL2) { + configAttribsPtr[0] = EGL_RENDERABLE_TYPE; + configAttribsPtr[1] = EGL_OPENGL_ES2_BIT; + configAttribsPtr += 2; + } + if (mUseDepth) { configAttribsPtr[0] = EGL_DEPTH_SIZE; configAttribsPtr[1] = 16; @@ -91,7 +100,11 @@ void Context::initEGL() //eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs); - mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, NULL); + if (useGL2) { + mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, context_attribs2); + } else { + mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, NULL); + } checkEglError("eglCreateContext"); if (mEGL.mContext == EGL_NO_CONTEXT) { LOGE("eglCreateContext returned EGL_NO_CONTEXT"); @@ -129,6 +142,13 @@ uint32_t Context::runScript(Script *s, uint32_t launchID) return ret; } +void Context::checkError(const char *msg) const +{ + GLenum err = glGetError(); + if (err != GL_NO_ERROR) { + LOGE("GL Error, 0x%x, from %s", err, msg); + } +} uint32_t Context::runRootScript() { @@ -156,11 +176,7 @@ uint32_t Context::runRootScript() mStateFragmentStore.mLast.clear(); uint32_t ret = runScript(mRootScript.get(), 0); - GLenum err = glGetError(); - if (err != GL_NO_ERROR) { - LOGE("Pending GL Error, 0x%x", err); - } - + checkError("runRootScript"); return ret; } @@ -225,10 +241,20 @@ void Context::timerPrint() void Context::setupCheck() { - mFragmentStore->setupGL(this, &mStateFragmentStore); - mFragment->setupGL(this, &mStateFragment); - mRaster->setupGL(this, &mStateRaster); - mVertex->setupGL(this, &mStateVertex); + if (checkVersion2_0()) { + mShaderCache.lookup(this, mVertex.get(), mFragment.get()); + + mFragmentStore->setupGL2(this, &mStateFragmentStore); + mFragment->setupGL2(this, &mStateFragment, &mShaderCache); + mRaster->setupGL2(this, &mStateRaster); + mVertex->setupGL2(this, &mStateVertex, &mShaderCache); + + } else { + mFragmentStore->setupGL(this, &mStateFragmentStore); + mFragment->setupGL(this, &mStateFragment); + mRaster->setupGL(this, &mStateRaster); + mVertex->setupGL(this, &mStateVertex); + } } static bool getProp(const char *str) @@ -248,11 +274,8 @@ void * Context::threadProc(void *vrsc) rsc->props.mLogTimes = getProp("debug.rs.profile"); rsc->props.mLogScripts = getProp("debug.rs.script"); - rsc->props.mLogObjects = getProp("debug.rs.objects"); - - //pthread_mutex_lock(&gInitMutex); - //rsc->initEGL(); - //pthread_mutex_unlock(&gInitMutex); + rsc->props.mLogObjects = getProp("debug.rs.object"); + rsc->props.mLogShaders = getProp("debug.rs.shader"); ScriptTLSStruct *tlsStruct = new ScriptTLSStruct; if (!tlsStruct) { @@ -274,6 +297,7 @@ void * Context::threadProc(void *vrsc) rsc->setFragment(NULL); rsc->mStateFragmentStore.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); rsc->setFragmentStore(NULL); + rsc->mStateVertexArray.init(rsc); rsc->mRunning = true; bool mDraw = true; @@ -319,10 +343,6 @@ void * Context::threadProc(void *vrsc) rsc->mObjDestroy.mNeedToEmpty = true; rsc->objDestroyOOBRun(); - glClearColor(0,0,0,0); - glClear(GL_COLOR_BUFFER_BIT); - eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface); - pthread_mutex_lock(&gInitMutex); rsc->deinitEGL(); pthread_mutex_unlock(&gInitMutex); @@ -457,7 +477,7 @@ void Context::setSurface(uint32_t w, uint32_t h, Surface *sur) if (!mEGL.mContext) { first = true; pthread_mutex_lock(&gInitMutex); - initEGL(); + initEGL(true); pthread_mutex_unlock(&gInitMutex); } @@ -488,15 +508,35 @@ void Context::setSurface(uint32_t w, uint32_t h, Surface *sur) //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion); LOGV("GL Version %s", mGL.mVersion); - LOGV("GL Vendor %s", mGL.mVendor); + //LOGV("GL Vendor %s", mGL.mVendor); LOGV("GL Renderer %s", mGL.mRenderer); //LOGV("GL Extensions %s", mGL.mExtensions); - if ((strlen((const char *)mGL.mVersion) < 12) || memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) { + const char *verptr = NULL; + if (strlen((const char *)mGL.mVersion) > 9) { + if (!memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) { + verptr = (const char *)mGL.mVersion + 12; + } + if (!memcmp(mGL.mVersion, "OpenGL ES ", 10)) { + verptr = (const char *)mGL.mVersion + 9; + } + } + + if (!verptr) { LOGE("Error, OpenGL ES Lite not supported"); } else { - sscanf((const char *)mGL.mVersion + 13, "%i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion); + sscanf(verptr, " %i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion); } + + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &mGL.mMaxVertexAttribs); + glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &mGL.mMaxVertexUniformVectors); + glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGL.mMaxVertexTextureUnits); + + glGetIntegerv(GL_MAX_VARYING_VECTORS, &mGL.mMaxVaryingVectors); + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGL.mMaxTextureImageUnits); + + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mGL.mMaxFragmentTextureImageUnits); + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGL.mMaxFragmentUniformVectors); } } @@ -544,13 +584,6 @@ void Context::setRaster(ProgramRaster *pr) } } -void Context::allocationCheck(const Allocation *a) -{ - mVertex->checkUpdatedAllocation(a); - mFragment->checkUpdatedAllocation(a); - mFragmentStore->checkUpdatedAllocation(a); -} - void Context::setVertex(ProgramVertex *pv) { if (pv == NULL) { @@ -558,7 +591,6 @@ void Context::setVertex(ProgramVertex *pv) } else { mVertex.set(pv); } - mVertex->forceDirty(); } void Context::assignName(ObjectBase *obj, const char *name, uint32_t len) @@ -600,26 +632,6 @@ void Context::appendNameDefines(String8 *str) const } } -void Context::appendVarDefines(String8 *str) const -{ - char buf[256]; - for (size_t ct=0; ct < mInt32Defines.size(); ct++) { - str->append("#define "); - str->append(mInt32Defines.keyAt(ct)); - str->append(" "); - sprintf(buf, "%i\n", (int)mInt32Defines.valueAt(ct)); - str->append(buf); - - } - for (size_t ct=0; ct < mFloatDefines.size(); ct++) { - str->append("#define "); - str->append(mFloatDefines.keyAt(ct)); - str->append(" "); - sprintf(buf, "%ff\n", mFloatDefines.valueAt(ct)); - str->append(buf); - } -} - bool Context::objDestroyOOBInit() { int status = pthread_mutex_init(&mObjDestroy.mMutex, NULL); @@ -751,6 +763,10 @@ void Context::dumpDebug() const LOGE(" RS running %i, exit %i, useDepth %i, paused %i", mRunning, mExit, mUseDepth, mPaused); LOGE(" RS pThreadID %li, nativeThreadID %i", mThreadId, mNativeThreadId); + LOGV("MAX Textures %i, %i %i", mGL.mMaxVertexTextureUnits, mGL.mMaxFragmentTextureImageUnits, mGL.mMaxTextureImageUnits); + LOGV("MAX Attribs %i", mGL.mMaxVertexAttribs); + LOGV("MAX Uniforms %i, %i", mGL.mMaxVertexUniformVectors, mGL.mMaxFragmentUniformVectors); + LOGV("MAX Varyings %i", mGL.mMaxVaryingVectors); } /////////////////////////////////////////////////////////////////////////////////////////// @@ -815,16 +831,6 @@ void rsi_ObjDestroy(Context *rsc, void *obj) ob->decUserRef(); } -void rsi_ContextSetDefineF(Context *rsc, const char* name, float value) -{ - rsc->addInt32Define(name, value); -} - -void rsi_ContextSetDefineI32(Context *rsc, const char* name, int32_t value) -{ - rsc->addFloatDefine(name, value); -} - void rsi_ContextPause(Context *rsc) { rsc->pause(); diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h index 1770ee6..2edd16d 100644 --- a/libs/rs/rsContext.h +++ b/libs/rs/rsContext.h @@ -37,6 +37,8 @@ #include "rsProgramFragmentStore.h" #include "rsProgramRaster.h" #include "rsProgramVertex.h" +#include "rsShaderCache.h" +#include "rsVertexArray.h" #include "rsgApiStructs.h" #include "rsLocklessFifo.h" @@ -72,8 +74,10 @@ public: ProgramRasterState mStateRaster; ProgramVertexState mStateVertex; LightState mStateLight; + VertexArrayState mStateVertexArray; ScriptCState mScriptC; + ShaderCache mShaderCache; void swapBuffers(); void setRootScript(Script *); @@ -90,7 +94,7 @@ public: const ProgramVertex * getVertex() {return mVertex.get();} void setupCheck(); - void allocationCheck(const Allocation *); + bool checkDriver() const {return mEGL.mSurface != 0;} void pause(); void resume(); @@ -101,7 +105,6 @@ public: void removeName(ObjectBase *obj); ObjectBase * lookupName(const char *name) const; void appendNameDefines(String8 *str) const; - void appendVarDefines(String8 *str) const; uint32_t getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait); bool sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace); @@ -123,14 +126,6 @@ public: return mStateRaster.mDefault.get(); } - void addInt32Define(const char* name, int32_t value) { - mInt32Defines.add(String8(name), value); - } - - void addFloatDefine(const char* name, float value) { - mFloatDefines.add(String8(name), value); - } - uint32_t getWidth() const {return mEGL.mWidth;} uint32_t getHeight() const {return mEGL.mHeight;} @@ -160,9 +155,11 @@ public: bool mLogTimes; bool mLogScripts; bool mLogObjects; + bool mLogShaders; } props; void dumpDebug() const; + void checkError(const char *) const; mutable const ObjectBase * mObjHead; @@ -190,6 +187,15 @@ protected: uint32_t mMajorVersion; uint32_t mMinorVersion; + int32_t mMaxVaryingVectors; + int32_t mMaxTextureImageUnits; + + int32_t mMaxFragmentTextureImageUnits; + int32_t mMaxFragmentUniformVectors; + + int32_t mMaxVertexAttribs; + int32_t mMaxVertexUniformVectors; + int32_t mMaxVertexTextureUnits; } mGL; uint32_t mWidth; @@ -224,7 +230,7 @@ protected: private: Context(); - void initEGL(); + void initEGL(bool useGL2); void deinitEGL(); uint32_t runRootScript(); @@ -234,8 +240,6 @@ private: Surface *mWndSurface; Vector<ObjectBase *> mNames; - KeyedVector<String8,int> mInt32Defines; - KeyedVector<String8,float> mFloatDefines; uint64_t mTimers[_RS_TIMER_TOTAL]; Timers mTimerActive; diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp index 67e4f14..207ad15 100644 --- a/libs/rs/rsElement.cpp +++ b/libs/rs/rsElement.cpp @@ -24,19 +24,13 @@ using namespace android::renderscript; Element::Element(Context *rsc) : ObjectBase(rsc) { + mBits = 0; mAllocFile = __FILE__; mAllocLine = __LINE__; - mComponents = NULL; - mComponentCount = 0; + mFields = NULL; + mFieldCount = 0; } -Element::Element(Context *rsc, uint32_t count) : ObjectBase(rsc) -{ - mAllocFile = __FILE__; - mAllocLine = __LINE__; - mComponents = new ObjectBaseRef<Component> [count]; - mComponentCount = count; -} Element::~Element() { @@ -45,153 +39,129 @@ Element::~Element() void Element::clear() { - delete [] mComponents; - mComponents = NULL; - mComponentCount = 0; + delete [] mFields; + mFields = NULL; + mFieldCount = 0; } -void Element::setComponent(uint32_t idx, Component *c) -{ - rsAssert(!mComponents[idx].get()); - rsAssert(idx < mComponentCount); - mComponents[idx].set(c); - -// Fixme: This should probably not be here - c->incUserRef(); -} - - size_t Element::getSizeBits() const { + if (!mFieldCount) { + return mBits; + } + size_t total = 0; - for (size_t ct=0; ct < mComponentCount; ct++) { - total += mComponents[ct]->getBits(); + for (size_t ct=0; ct < mFieldCount; ct++) { + total += mFields[ct].e->mBits; } return total; } -size_t Element::getComponentOffsetBits(uint32_t componentNumber) const +size_t Element::getFieldOffsetBits(uint32_t componentNumber) const { size_t offset = 0; for (uint32_t ct = 0; ct < componentNumber; ct++) { - offset += mComponents[ct]->getBits(); + offset += mFields[ct].e->mBits; } return offset; } -uint32_t Element::getGLType() const +void Element::dumpLOGV(const char *prefix) const { - int bits[4]; + ObjectBase::dumpLOGV(prefix); + LOGV("%s Element: components %i, size %i", prefix, mFieldCount, mBits); + for (uint32_t ct = 0; ct < mFieldCount; ct++) { + char buf[1024]; + sprintf(buf, "%s component %i: ", prefix, ct); + //mComponents[ct]->dumpLOGV(buf); + } +} + + +Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk, + bool isNorm, uint32_t vecSize) +{ + Element *e = new Element(rsc); + e->mComponent.set(dt, dk, isNorm, vecSize); + e->mBits = e->mComponent.getBits(); + return e; +} + +Element * Element::create(Context *rsc, size_t count, const Element **ein, + const char **nin, const size_t * lengths) +{ + Element *e = new Element(rsc); + e->mFields = new ElementField_t [count]; + e->mFieldCount = count; - if (mComponentCount > 4) { - return 0; + for (size_t ct=0; ct < count; ct++) { + e->mFields[ct].e.set(ein[ct]); + e->mFields[ct].name.setTo(nin[ct], lengths[ct]); } - for (uint32_t ct=0; ct < mComponentCount; ct++) { - bits[ct] = mComponents[ct]->getBits(); - if (mComponents[ct]->getType() != Component::UNSIGNED) { - return 0; - } - if (!mComponents[ct]->getIsNormalized()) { - return 0; - } + return e; +} + +String8 Element::getCStructBody(uint32_t indent) const +{ + String8 si; + for (uint32_t ct=0; ct < indent; ct++) { + si.append(" "); } - switch(mComponentCount) { - case 1: - if (bits[0] == 8) { - return GL_UNSIGNED_BYTE; - } - return 0; - case 2: - if ((bits[0] == 8) && - (bits[1] == 8)) { - return GL_UNSIGNED_BYTE; - } - return 0; - case 3: - if ((bits[0] == 8) && - (bits[1] == 8) && - (bits[2] == 8)) { - return GL_UNSIGNED_BYTE; - } - if ((bits[0] == 5) && - (bits[1] == 6) && - (bits[2] == 5)) { - return GL_UNSIGNED_SHORT_5_6_5; - } - return 0; - case 4: - if ((bits[0] == 8) && - (bits[1] == 8) && - (bits[2] == 8) && - (bits[3] == 8)) { - return GL_UNSIGNED_BYTE; - } - if ((bits[0] == 4) && - (bits[1] == 4) && - (bits[2] == 4) && - (bits[3] == 4)) { - return GL_UNSIGNED_SHORT_4_4_4_4; - } - if ((bits[0] == 5) && - (bits[1] == 5) && - (bits[2] == 5) && - (bits[3] == 1)) { - return GL_UNSIGNED_SHORT_5_5_5_1; - } + String8 s(si); + s.append("{\n"); + for (uint32_t ct = 0; ct < mFieldCount; ct++) { + s.append(si); + s.append(mFields[ct].e->getCType(indent+4)); + s.append(" "); + s.append(mFields[ct].name); + s.append(";\n"); } - return 0; + s.append(si); + s.append("}"); + return s; } -uint32_t Element::getGLFormat() const +String8 Element::getCType(uint32_t indent) const { - switch(mComponentCount) { - case 1: - if (mComponents[0]->getKind() == Component::ALPHA) { - return GL_ALPHA; - } - if (mComponents[0]->getKind() == Component::LUMINANCE) { - return GL_LUMINANCE; - } - break; - case 2: - if ((mComponents[0]->getKind() == Component::LUMINANCE) && - (mComponents[1]->getKind() == Component::ALPHA)) { - return GL_LUMINANCE_ALPHA; - } - break; - case 3: - if ((mComponents[0]->getKind() == Component::RED) && - (mComponents[1]->getKind() == Component::GREEN) && - (mComponents[2]->getKind() == Component::BLUE)) { - return GL_RGB; - } - break; - case 4: - if ((mComponents[0]->getKind() == Component::RED) && - (mComponents[1]->getKind() == Component::GREEN) && - (mComponents[2]->getKind() == Component::BLUE) && - (mComponents[3]->getKind() == Component::ALPHA)) { - return GL_RGBA; - } - break; + String8 s; + for (uint32_t ct=0; ct < indent; ct++) { + s.append(" "); + } + + if (!mFieldCount) { + // Basic component. + s.append(mComponent.getCType()); + } else { + s.append("struct "); + s.append(getCStructBody(indent)); } - return 0; -} + return s; +} -void Element::dumpLOGV(const char *prefix) const +String8 Element::getGLSLType(uint32_t indent) const { - ObjectBase::dumpLOGV(prefix); - LOGV("%s Element: components %i, size %i", prefix, mComponentCount, getSizeBytes()); - for (uint32_t ct = 0; ct < mComponentCount; ct++) { - char buf[1024]; - sprintf(buf, "%s component %i: ", prefix, ct); - mComponents[ct]->dumpLOGV(buf); + String8 s; + for (uint32_t ct=0; ct < indent; ct++) { + s.append(" "); } + + if (!mFieldCount) { + // Basic component. + s.append(mComponent.getGLSLType()); + } else { + rsAssert(0); + //s.append("struct "); + //s.append(getCStructBody(indent)); + } + + return s; } + + ElementState::ElementState() { } @@ -200,46 +170,35 @@ ElementState::~ElementState() { } + ///////////////////////////////////////// // namespace android { namespace renderscript { -void rsi_ElementBegin(Context *rsc) -{ - rsc->mStateElement.mComponentBuildList.clear(); -} - -void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalized, size_t bits, const char *name) +RsElement rsi_ElementCreate(Context *rsc, + RsDataType dt, + RsDataKind dk, + bool norm, + uint32_t vecSize) { - ElementState * sec = &rsc->mStateElement; - - rsAssert(bits > 0); - - Component *c = new Component(rsc, - static_cast<Component::DataKind>(dk), - static_cast<Component::DataType>(dt), - isNormalized, - bits, - name); - sec->mComponentBuildList.add(c); + //LOGE("rsi_ElementCreate %i %i %i %i", dt, dk, norm, vecSize); + Element *e = Element::create(rsc, dt, dk, norm, vecSize); + e->incUserRef(); + return e; } -RsElement rsi_ElementCreate(Context *rsc) +RsElement rsi_ElementCreate2(Context *rsc, + size_t count, + const RsElement * ein, + const char ** names, + const size_t * nameLengths) { - ElementState * sec = &rsc->mStateElement; - Element *se = new Element(rsc, sec->mComponentBuildList.size()); - - rsAssert(se->getComponentCount() > 0); - - for (size_t ct = 0; ct < se->getComponentCount(); ct++) { - se->setComponent(ct, sec->mComponentBuildList[ct]); - } - - rsc->mStateElement.mComponentBuildList.clear(); - se->incUserRef(); - return se; + //LOGE("rsi_ElementCreate2 %i", count); + Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths); + e->incUserRef(); + return e; } diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h index b41c552..777e8ee 100644 --- a/libs/rs/rsElement.h +++ b/libs/rs/rsElement.h @@ -18,6 +18,8 @@ #define ANDROID_STRUCTURED_ELEMENT_H #include "rsComponent.h" +#include "rsUtils.h" +#include "rsObjectBase.h" // --------------------------------------------------------------------------- namespace android { @@ -28,41 +30,57 @@ namespace renderscript { class Element : public ObjectBase { public: - Element(Context *, uint32_t count); ~Element(); - - void setComponent(uint32_t idx, Component *c); - uint32_t getGLType() const; uint32_t getGLFormat() const; - size_t getSizeBits() const; size_t getSizeBytes() const { return (getSizeBits() + 7) >> 3; } - size_t getComponentOffsetBits(uint32_t componentNumber) const; - size_t getComponentOffsetBytes(uint32_t componentNumber) const { - return (getComponentOffsetBits(componentNumber) + 7) >> 3; + size_t getFieldOffsetBits(uint32_t componentNumber) const; + size_t getFieldOffsetBytes(uint32_t componentNumber) const { + return (getFieldOffsetBits(componentNumber) + 7) >> 3; } - uint32_t getComponentCount() const {return mComponentCount;} - Component * getComponent(uint32_t idx) const {return mComponents[idx].get();} + uint32_t getFieldCount() const {return mFieldCount;} + const Element * getField(uint32_t idx) const {return mFields[idx].e.get();} + const char * getFieldName(uint32_t idx) const {return mFields[idx].name.string();} + + const Component & getComponent() const {return mComponent;} + RsDataType getType() const {return mComponent.getType();} + RsDataKind getKind() const {return mComponent.getKind();} + uint32_t getBits() const {return mBits;} + String8 getCType(uint32_t indent=0) const; + String8 getCStructBody(uint32_t indent=0) const; + String8 getGLSLType(uint32_t indent=0) const; void dumpLOGV(const char *prefix) const; + static Element * create(Context *rsc, RsDataType dt, RsDataKind dk, + bool isNorm, uint32_t vecSize); + static Element * create(Context *rsc, size_t count, const Element **, + const char **, const size_t * lengths); + protected: // deallocate any components that are part of this element. void clear(); - size_t mComponentCount; - ObjectBaseRef<Component> * mComponents; - //uint32_t *mOffsetTable; + typedef struct { + String8 name; + ObjectBaseRef<const Element> e; + } ElementField_t; + ElementField_t *mFields; + size_t mFieldCount; + Element(Context *); + + Component mComponent; + uint32_t mBits; }; @@ -71,7 +89,6 @@ public: ElementState(); ~ElementState(); - Vector<Component *> mComponentBuildList; }; diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp index c566665..e3272c5 100644 --- a/libs/rs/rsFileA3D.cpp +++ b/libs/rs/rsFileA3D.cpp @@ -324,6 +324,7 @@ void FileA3D::processChunk_Verticies(Context *rsc, IO *io, A3DIndexEntry *ie) void FileA3D::processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie) { + /* rsi_ElementBegin(rsc); uint32_t count = io->loadU32(); @@ -338,6 +339,7 @@ void FileA3D::processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie) } LOGE("processChunk_Element create"); ie->mRsObj = rsi_ElementCreate(rsc); + */ } void FileA3D::processChunk_ElementSource(Context *rsc, IO *io, A3DIndexEntry *ie) diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp index 5f2a609..656a3c3 100644 --- a/libs/rs/rsProgram.cpp +++ b/libs/rs/rsProgram.cpp @@ -17,34 +17,245 @@ #include "rsContext.h" #include "rsProgram.h" +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + using namespace android; using namespace android::renderscript; -Program::Program(Context *rsc, Element *in, Element *out) : ObjectBase(rsc) +Program::Program(Context *rsc) : ObjectBase(rsc) { mAllocFile = __FILE__; mAllocLine = __LINE__; + mDirty = true; + mShaderID = 0; + mAttribCount = 0; + mUniformCount = 0; + + mInputElements = NULL; + mOutputElements = NULL; + mConstantTypes = NULL; + mInputCount = 0; + mOutputCount = 0; + mConstantCount = 0; +} + +Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, + const uint32_t * params, uint32_t paramLength) : + ObjectBase(rsc) +{ + mAllocFile = __FILE__; + mAllocLine = __LINE__; + mDirty = true; + mShaderID = 0; + mAttribCount = 0; + mUniformCount = 0; + mTextureCount = 0; - mElementIn.set(in); - mElementOut.set(out); + mInputCount = 0; + mOutputCount = 0; + mConstantCount = 0; + + for (uint32_t ct=0; ct < paramLength; ct+=2) { + if (params[ct] == RS_PROGRAM_PARAM_INPUT) { + mInputCount++; + } + if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) { + mOutputCount++; + } + if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) { + mConstantCount++; + } + if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_COUNT) { + mTextureCount = params[ct+1]; + } + } + + mInputElements = new ObjectBaseRef<Element>[mInputCount]; + mOutputElements = new ObjectBaseRef<Element>[mOutputCount]; + mConstantTypes = new ObjectBaseRef<Type>[mConstantCount]; + + uint32_t input = 0; + uint32_t output = 0; + uint32_t constant = 0; + for (uint32_t ct=0; ct < paramLength; ct+=2) { + if (params[ct] == RS_PROGRAM_PARAM_INPUT) { + mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1])); + } + if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) { + mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1])); + } + if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) { + mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1])); + } + } + mUserShader.setTo(shaderText, shaderLength); } Program::~Program() { + for (uint32_t ct=0; ct < MAX_UNIFORMS; ct++) { + bindAllocation(NULL, ct); + } + + delete[] mInputElements; + delete[] mOutputElements; + delete[] mConstantTypes; + mInputCount = 0; + mOutputCount = 0; + mConstantCount = 0; +} + + +void Program::bindAllocation(Allocation *alloc, uint32_t slot) +{ + if (mConstants[slot].get() == alloc) { + return; + } + if (mConstants[slot].get()) { + mConstants[slot].get()->removeProgramToDirty(this); + } + mConstants[slot].set(alloc); + if (alloc) { + alloc->addProgramToDirty(this); + } + mDirty = true; } +void Program::bindTexture(uint32_t slot, Allocation *a) +{ + if (slot >= MAX_TEXTURE) { + LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE"); + return; + } + + //LOGE("bindtex %i %p", slot, a); + mTextures[slot].set(a); + mDirty = true; +} -void Program::bindAllocation(Allocation *alloc) +void Program::bindSampler(uint32_t slot, Sampler *s) { - mConstants.set(alloc); + if (slot >= MAX_TEXTURE) { + LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE"); + return; + } + + mSamplers[slot].set(s); mDirty = true; } -void Program::checkUpdatedAllocation(const Allocation *alloc) +String8 Program::getGLSLInputString() const +{ + String8 s; + for (uint32_t ct=0; ct < mInputCount; ct++) { + const Element *e = mInputElements[ct].get(); + for (uint32_t field=0; field < e->getFieldCount(); field++) { + const Element *f = e->getField(field); + + // Cannot be complex + rsAssert(!f->getFieldCount()); + switch(f->getComponent().getVectorSize()) { + case 1: s.append("attribute float ATTRIB_"); break; + case 2: s.append("attribute vec2 ATTRIB_"); break; + case 3: s.append("attribute vec3 ATTRIB_"); break; + case 4: s.append("attribute vec4 ATTRIB_"); break; + default: + rsAssert(0); + } + + s.append(e->getFieldName(field)); + s.append(";\n"); + } + } + return s; +} + +String8 Program::getGLSLOutputString() const +{ + return String8(); +} + +String8 Program::getGLSLConstantString() const +{ + return String8(); +} + + +void Program::createShader() +{ +} + +bool Program::loadShader(Context *rsc, uint32_t type) { - if (mConstants.get() == alloc) { - mDirty = true; + mShaderID = glCreateShader(type); + rsAssert(mShaderID); + + if (rsc->props.mLogShaders) { + LOGV("Loading shader type %x, ID %i", type, mShaderID); + LOGV(mShader.string()); } + + if (mShaderID) { + const char * ss = mShader.string(); + glShaderSource(mShaderID, 1, &ss, NULL); + glCompileShader(mShaderID); + + GLint compiled = 0; + glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint infoLen = 0; + glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen) { + char* buf = (char*) malloc(infoLen); + if (buf) { + glGetShaderInfoLog(mShaderID, infoLen, NULL, buf); + LOGE("Could not compile shader \n%s\n", buf); + free(buf); + } + glDeleteShader(mShaderID); + mShaderID = 0; + return false; + } + } + } + + if (rsc->props.mLogShaders) { + LOGV("--Shader load result %x ", glGetError()); + } + return true; +} + +void Program::setShader(const char *txt, uint32_t len) +{ + mUserShader.setTo(txt, len); +} + + + +namespace android { +namespace renderscript { + + +void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants) +{ + Program *p = static_cast<Program *>(vp); + p->bindAllocation(static_cast<Allocation *>(constants), slot); +} + +void rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a) +{ + Program *p = static_cast<Program *>(vpf); + p->bindTexture(slot, static_cast<Allocation *>(a)); +} + +void rsi_ProgramBindSampler(Context *rsc, RsProgram vpf, uint32_t slot, RsSampler s) +{ + Program *p = static_cast<Program *>(vpf); + p->bindSampler(slot, static_cast<Sampler *>(s)); +} + +} } diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h index 57c654f..238ee7f 100644 --- a/libs/rs/rsProgram.h +++ b/libs/rs/rsProgram.h @@ -25,29 +25,78 @@ namespace android { namespace renderscript { +class ShaderCache; class Program : public ObjectBase { public: - Program(Context *, Element *in, Element *out); + const static uint32_t MAX_ATTRIBS = 8; + const static uint32_t MAX_UNIFORMS = 16; + const static uint32_t MAX_TEXTURE = 2; + + Program(Context *); + Program(Context *, const char * shaderText, uint32_t shaderLength, + const uint32_t * params, uint32_t paramLength); virtual ~Program(); - void bindAllocation(Allocation *); - void checkUpdatedAllocation(const Allocation *); + void bindAllocation(Allocation *, uint32_t slot); + virtual void createShader(); + + bool isUserProgram() const {return mUserShader.size() > 0;} + + void bindTexture(uint32_t slot, Allocation *); + void bindSampler(uint32_t slot, Sampler *); + + uint32_t getShaderID() const {return mShaderID;} + void setShader(const char *, uint32_t len); + + uint32_t getAttribCount() const {return mAttribCount;} + uint32_t getUniformCount() const {return mUniformCount;} + const String8 & getAttribName(uint32_t i) const {return mAttribNames[i];} + const String8 & getUniformName(uint32_t i) const {return mUniformNames[i];} + + String8 getGLSLInputString() const; + String8 getGLSLOutputString() const; + String8 getGLSLConstantString() const; + + const Allocation * getTexture(uint32_t i) const {return mTextures[i].get();} protected: // Components not listed in "in" will be passed though // unless overwritten by components in out. - ObjectBaseRef<Element> mElementIn; - ObjectBaseRef<Element> mElementOut; + ObjectBaseRef<Element> *mInputElements; + ObjectBaseRef<Element> *mOutputElements; + ObjectBaseRef<Type> *mConstantTypes; + uint32_t mInputCount; + uint32_t mOutputCount; + uint32_t mConstantCount; - ObjectBaseRef<Allocation> mConstants; + ObjectBaseRef<Allocation> mConstants[MAX_UNIFORMS]; mutable bool mDirty; - + String8 mShader; + String8 mUserShader; + uint32_t mShaderID; + + uint32_t mTextureCount; + uint32_t mAttribCount; + uint32_t mUniformCount; + String8 mAttribNames[MAX_ATTRIBS]; + String8 mUniformNames[MAX_UNIFORMS]; + + // The difference between Textures and Constants is how they are accessed + // Texture lookups go though a sampler which in effect converts normalized + // coordinates into type specific. Multiple samples may also be taken + // and filtered. + // + // Constants are strictly accessed by programetic loads. + ObjectBaseRef<Allocation> mTextures[MAX_TEXTURE]; + ObjectBaseRef<Sampler> mSamplers[MAX_TEXTURE]; + + bool loadShader(Context *, uint32_t type); public: - void forceDirty() {mDirty = true;} + void forceDirty() const {mDirty = true;} }; diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp index 5f2dfae..15f3269 100644 --- a/libs/rs/rsProgramFragment.cpp +++ b/libs/rs/rsProgramFragment.cpp @@ -19,25 +19,50 @@ #include <GLES/gl.h> #include <GLES/glext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> using namespace android; using namespace android::renderscript; -ProgramFragment::ProgramFragment(Context *rsc, Element *in, Element *out, bool pointSpriteEnable) : - Program(rsc, in, out) +ProgramFragment::ProgramFragment(Context *rsc, const uint32_t * params, + uint32_t paramLength) : + Program(rsc) { mAllocFile = __FILE__; mAllocLine = __LINE__; - for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { - mEnvModes[ct] = RS_TEX_ENV_MODE_REPLACE; - mTextureDimensions[ct] = 2; - } + rsAssert(paramLength = 5); + + mEnvModes[0] = (RsTexEnvMode)params[0]; + mTextureFormats[0] = params[1]; + mEnvModes[1] = (RsTexEnvMode)params[2]; + mTextureFormats[1] = params[3]; + mPointSpriteEnable = params[4] != 0; + mTextureEnableMask = 0; - mPointSpriteEnable = pointSpriteEnable; - mEnvModes[1] = RS_TEX_ENV_MODE_DECAL; + if (mEnvModes[0]) { + mTextureEnableMask |= 1; + } + if (mEnvModes[1]) { + mTextureEnableMask |= 2; + } + init(rsc); } +ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText, + uint32_t shaderLength, const uint32_t * params, + uint32_t paramLength) : + Program(rsc, shaderText, shaderLength, params, paramLength) +{ + mAllocFile = __FILE__; + mAllocLine = __LINE__; + + init(rsc); + mTextureEnableMask = (1 << mTextureCount) -1; +} + + ProgramFragment::~ProgramFragment() { } @@ -65,23 +90,13 @@ void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state) } glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable); } - - rsAssert(mTextures[ct]->getTextureID() != 0); - if (mTextures[ct]->getTextureID() == 0) { - // This is a hack for eclair to try to fix the white squares bug. - Allocation *a = (Allocation *)mTextures[ct].get(); - a->uploadToTexture((Context *)rsc, 0); - if (mTextures[ct]->getTextureID() == 0) { - // At this point we are screwed. Crash to restart the app. - rsc->dumpDebug(); - LOGE("Multiple failures during texture upload. Driver appears wedged."); - ((char *)0)[0] = 0; - } - - } + mTextures[ct]->uploadCheck(rsc); glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); switch(mEnvModes[ct]) { + case RS_TEX_ENV_MODE_NONE: + rsAssert(0); + break; case RS_TEX_ENV_MODE_REPLACE: glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); break; @@ -94,7 +109,7 @@ void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state) } if (mSamplers[ct].get()) { - mSamplers[ct]->setupGL(); + mSamplers[ct]->setupGL(rsc); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -121,73 +136,158 @@ void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state) } glActiveTexture(GL_TEXTURE0); mDirty = false; + rsc->checkError("ProgramFragment::setupGL"); } - -void ProgramFragment::bindTexture(uint32_t slot, Allocation *a) +void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc) { - if (slot >= MAX_TEXTURE) { - LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE"); - return; + + //LOGE("sgl2 frag1 %x", glGetError()); + if ((state->mLast.get() == this) && !mDirty) { + //return; } + state->mLast.set(this); - //LOGE("bindtex %i %p", slot, a); - mTextures[slot].set(a); - mDirty = true; -} + rsc->checkError("ProgramFragment::setupGL2 start"); + for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { + glActiveTexture(GL_TEXTURE0 + ct); + if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) { + continue; + } -void ProgramFragment::bindSampler(uint32_t slot, Sampler *s) -{ - if (slot >= MAX_TEXTURE) { - LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE"); - return; + mTextures[ct]->uploadCheck(rsc); + glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); + rsc->checkError("ProgramFragment::setupGL2 tex bind"); + if (mSamplers[ct].get()) { + mSamplers[ct]->setupGL(rsc); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + rsc->checkError("ProgramFragment::setupGL2 tex env"); + } + + glUniform1i(sc->fragUniformSlot(ct), ct); + rsc->checkError("ProgramFragment::setupGL2 uniforms"); } - mSamplers[slot].set(s); - mDirty = true; + glActiveTexture(GL_TEXTURE0); + mDirty = false; + rsc->checkError("ProgramFragment::setupGL2"); +} + +void ProgramFragment::loadShader(Context *rsc) { + Program::loadShader(rsc, GL_FRAGMENT_SHADER); } -void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim) +void ProgramFragment::createShader() { - if (slot >= MAX_TEXTURE) { - LOGE("Attempt to setType to a slot > MAX_TEXTURE"); - return; - } + mShader.setTo("precision mediump float;\n"); + mShader.append("varying vec4 varColor;\n"); + mShader.append("varying vec4 varTex0;\n"); + + if (mUserShader.length() > 1) { + for (uint32_t ct=0; ct < mTextureCount; ct++) { + char buf[256]; + sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct); + mShader.append(buf); + } - if (dim >= 4) { - LOGE("Attempt to setType to a dimension > 3"); - return; - } + mShader.append(mUserShader); + } else { + uint32_t mask = mTextureEnableMask; + uint32_t texNum = 0; + while (mask) { + if (mask & 1) { + char buf[64]; + mShader.append("uniform sampler2D uni_Tex"); + sprintf(buf, "%i", texNum); + mShader.append(buf); + mShader.append(";\n"); + } + mask >>= 1; + texNum++; + } - mTextureFormats[slot].set(e); - mTextureDimensions[slot] = dim; -} -void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env) -{ - if (slot >= MAX_TEXTURE) { - LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE"); - return; - } + mShader.append("void main() {\n"); + mShader.append(" vec4 col = varColor;\n"); - mEnvModes[slot] = env; -} + if (mTextureEnableMask) { + if (mPointSpriteEnable) { + mShader.append(" vec2 t0 = gl_PointCoord;\n"); + } else { + mShader.append(" vec2 t0 = varTex0.xy;\n"); + } + } -void ProgramFragment::setTexEnable(uint32_t slot, bool enable) -{ - if (slot >= MAX_TEXTURE) { - LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE"); - return; - } + mask = mTextureEnableMask; + texNum = 0; + while (mask) { + if (mask & 1) { + switch(mEnvModes[texNum]) { + case RS_TEX_ENV_MODE_NONE: + rsAssert(0); + break; + case RS_TEX_ENV_MODE_REPLACE: + switch(mTextureFormats[texNum]) { + case 1: + mShader.append(" col.a = texture2D(uni_Tex0, t0).a;\n"); + break; + case 2: + mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n"); + break; + case 3: + mShader.append(" col.rgb = texture2D(uni_Tex0, t0).rgb;\n"); + break; + case 4: + mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n"); + break; + } + break; + case RS_TEX_ENV_MODE_MODULATE: + switch(mTextureFormats[texNum]) { + case 1: + mShader.append(" col.a *= texture2D(uni_Tex0, t0).a;\n"); + break; + case 2: + mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n"); + break; + case 3: + mShader.append(" col.rgb *= texture2D(uni_Tex0, t0).rgb;\n"); + break; + case 4: + mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n"); + break; + } + break; + case RS_TEX_ENV_MODE_DECAL: + mShader.append(" col = texture2D(uni_Tex0, t0);\n"); + break; + } - uint32_t bit = 1 << slot; - mTextureEnableMask &= ~bit; - if (enable) { - mTextureEnableMask |= bit; + } + mask >>= 1; + texNum++; + } + + //mShader.append(" col.a = 1.0;\n"); + //mShader.append(" col.r = 0.5;\n"); + + mShader.append(" gl_FragColor = col;\n"); + mShader.append("}\n"); } } +void ProgramFragment::init(Context *rsc) +{ + mUniformCount = 2; + mUniformNames[0].setTo("uni_Tex0"); + mUniformNames[1].setTo("uni_Tex1"); + createShader(); +} ProgramFragmentState::ProgramFragmentState() { @@ -202,8 +302,14 @@ ProgramFragmentState::~ProgramFragmentState() void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h) { - ProgramFragment *pf = new ProgramFragment(rsc, NULL, NULL, false); + uint32_t tmp[5] = { + RS_TEX_ENV_MODE_NONE, 0, + RS_TEX_ENV_MODE_NONE, 0, + 0 + }; + ProgramFragment *pf = new ProgramFragment(rsc, tmp, 5); mDefault.set(pf); + pf->init(rsc); } void ProgramFragmentState::deinit(Context *rsc) @@ -216,50 +322,24 @@ void ProgramFragmentState::deinit(Context *rsc) namespace android { namespace renderscript { -void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out, bool pointSpriteEnable) +RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc, + const uint32_t * params, + uint32_t paramLength) { - delete rsc->mStateFragment.mPF; - rsc->mStateFragment.mPF = new ProgramFragment(rsc, (Element *)in, (Element *)out, pointSpriteEnable); -} - -void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a) -{ - ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); - pf->bindTexture(slot, static_cast<Allocation *>(a)); -} - -void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s) -{ - ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); - pf->bindSampler(slot, static_cast<Sampler *>(s)); -} - -void rsi_ProgramFragmentSetSlot(Context *rsc, uint32_t slot, bool enable, RsTexEnvMode env, RsType vt) -{ - const Type *t = static_cast<const Type *>(vt); - if (t) { - uint32_t dim = 1; - if (t->getDimY()) { - dim ++; - if (t->getDimZ()) { - dim ++; - } - } - rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim); - } - rsc->mStateFragment.mPF->setEnvMode(slot, env); - rsc->mStateFragment.mPF->setTexEnable(slot, enable); + ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength); + pf->incUserRef(); + return pf; } -RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc) +RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText, + uint32_t shaderLength, const uint32_t * params, + uint32_t paramLength) { - ProgramFragment *pf = rsc->mStateFragment.mPF; + ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength); pf->incUserRef(); - rsc->mStateFragment.mPF = 0; return pf; } - } } diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h index e26c6e8..9fa565d 100644 --- a/libs/rs/rsProgramFragment.h +++ b/libs/rs/rsProgramFragment.h @@ -28,40 +28,23 @@ class ProgramFragmentState; class ProgramFragment : public Program { public: - const static uint32_t MAX_TEXTURE = 2; - - - - ProgramFragment(Context *, Element *in, Element *out, bool pointSpriteEnable); + ProgramFragment(Context *, const uint32_t * params, uint32_t paramLength); + ProgramFragment(Context *rsc, const char * shaderText, + uint32_t shaderLength, const uint32_t * params, + uint32_t paramLength); virtual ~ProgramFragment(); virtual void setupGL(const Context *, ProgramFragmentState *); + virtual void setupGL2(const Context *, ProgramFragmentState *, ShaderCache *sc); - - - void bindTexture(uint32_t slot, Allocation *); - void bindSampler(uint32_t slot, Sampler *); - void setType(uint32_t slot, const Element *, uint32_t dim); - - void setEnvMode(uint32_t slot, RsTexEnvMode); - void setTexEnable(uint32_t slot, bool); - - + virtual void createShader(); + virtual void loadShader(Context *rsc); + virtual void init(Context *rsc); protected: - // The difference between Textures and Constants is how they are accessed - // Texture lookups go though a sampler which in effect converts normalized - // coordinates into type specific. Multiple samples may also be taken - // and filtered. - // - // Constants are strictly accessed by programetic loads. - ObjectBaseRef<Allocation> mTextures[MAX_TEXTURE]; - ObjectBaseRef<Sampler> mSamplers[MAX_TEXTURE]; - ObjectBaseRef<const Element> mTextureFormats[MAX_TEXTURE]; - uint32_t mTextureDimensions[MAX_TEXTURE]; - - // Hacks to create a program for now + uint32_t mTextureFormats[MAX_TEXTURE]; + uint32_t mTextureDimensions[MAX_TEXTURE]; RsTexEnvMode mEnvModes[MAX_TEXTURE]; uint32_t mTextureEnableMask; bool mPointSpriteEnable; diff --git a/libs/rs/rsProgramFragmentStore.cpp b/libs/rs/rsProgramFragmentStore.cpp index de33d9c..8a2157f 100644 --- a/libs/rs/rsProgramFragmentStore.cpp +++ b/libs/rs/rsProgramFragmentStore.cpp @@ -24,8 +24,8 @@ using namespace android; using namespace android::renderscript; -ProgramFragmentStore::ProgramFragmentStore(Context *rsc, Element *in, Element *out) : - Program(rsc, in, out) +ProgramFragmentStore::ProgramFragmentStore(Context *rsc) : + Program(rsc) { mAllocFile = __FILE__; mAllocLine = __LINE__; @@ -83,10 +83,44 @@ void ProgramFragmentStore::setupGL(const Context *rsc, ProgramFragmentStoreState } else { glDisable(GL_DITHER); } +} +void ProgramFragmentStore::setupGL2(const Context *rsc, ProgramFragmentStoreState *state) +{ + if (state->mLast.get() == this) { + return; + } + state->mLast.set(this); + + glColorMask(mColorRWriteEnable, + mColorGWriteEnable, + mColorBWriteEnable, + mColorAWriteEnable); + if (mBlendEnable) { + glEnable(GL_BLEND); + glBlendFunc(mBlendSrc, mBlendDst); + } else { + glDisable(GL_BLEND); + } + //LOGE("pfs %i, %i, %x", mDepthWriteEnable, mDepthTestEnable, mDepthFunc); + + glDepthMask(mDepthWriteEnable); + if(mDepthTestEnable || mDepthWriteEnable) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(mDepthFunc); + } else { + glDisable(GL_DEPTH_TEST); + } + + if (mDitherEnable) { + glEnable(GL_DITHER); + } else { + glDisable(GL_DITHER); + } } + void ProgramFragmentStore::setDitherEnable(bool enable) { mDitherEnable = enable; @@ -215,7 +249,7 @@ ProgramFragmentStoreState::~ProgramFragmentStoreState() void ProgramFragmentStoreState::init(Context *rsc, int32_t w, int32_t h) { - ProgramFragmentStore *pfs = new ProgramFragmentStore(rsc, NULL, NULL); + ProgramFragmentStore *pfs = new ProgramFragmentStore(rsc); mDefault.set(pfs); } @@ -232,7 +266,7 @@ namespace renderscript { void rsi_ProgramFragmentStoreBegin(Context * rsc, RsElement in, RsElement out) { delete rsc->mStateFragmentStore.mPFS; - rsc->mStateFragmentStore.mPFS = new ProgramFragmentStore(rsc, (Element *)in, (Element *)out); + rsc->mStateFragmentStore.mPFS = new ProgramFragmentStore(rsc); } diff --git a/libs/rs/rsProgramFragmentStore.h b/libs/rs/rsProgramFragmentStore.h index a344387..3412c99 100644 --- a/libs/rs/rsProgramFragmentStore.h +++ b/libs/rs/rsProgramFragmentStore.h @@ -28,10 +28,11 @@ class ProgramFragmentStoreState; class ProgramFragmentStore : public Program { public: - ProgramFragmentStore(Context *, Element *in, Element *out); + ProgramFragmentStore(Context *); virtual ~ProgramFragmentStore(); virtual void setupGL(const Context *, ProgramFragmentStoreState *); + virtual void setupGL2(const Context *, ProgramFragmentStoreState *); void setDepthFunc(RsDepthFunc); void setDepthMask(bool); diff --git a/libs/rs/rsProgramRaster.cpp b/libs/rs/rsProgramRaster.cpp index 51ae7cf..13887d1 100644 --- a/libs/rs/rsProgramRaster.cpp +++ b/libs/rs/rsProgramRaster.cpp @@ -25,12 +25,10 @@ using namespace android::renderscript; ProgramRaster::ProgramRaster(Context *rsc, - Element *in, - Element *out, bool pointSmooth, bool lineSmooth, bool pointSprite) : - Program(rsc, in, out) + Program(rsc) { mAllocFile = __FILE__; mAllocLine = __LINE__; @@ -86,6 +84,14 @@ void ProgramRaster::setupGL(const Context *rsc, ProgramRasterState *state) } } +void ProgramRaster::setupGL2(const Context *rsc, ProgramRasterState *state) +{ + if (state->mLast.get() == this) { + return; + } + state->mLast.set(this); +} + ProgramRasterState::ProgramRasterState() @@ -98,7 +104,7 @@ ProgramRasterState::~ProgramRasterState() void ProgramRasterState::init(Context *rsc, int32_t w, int32_t h) { - ProgramRaster *pr = new ProgramRaster(rsc, NULL, NULL, false, false, false); + ProgramRaster *pr = new ProgramRaster(rsc, false, false, false); mDefault.set(pr); } @@ -118,8 +124,6 @@ RsProgramRaster rsi_ProgramRasterCreate(Context * rsc, RsElement in, RsElement o bool pointSprite) { ProgramRaster *pr = new ProgramRaster(rsc, - static_cast<Element *>(in), - static_cast<Element *>(out), pointSmooth, lineSmooth, pointSprite); diff --git a/libs/rs/rsProgramRaster.h b/libs/rs/rsProgramRaster.h index a6d5ba8..c3a9c90 100644 --- a/libs/rs/rsProgramRaster.h +++ b/libs/rs/rsProgramRaster.h @@ -29,14 +29,13 @@ class ProgramRaster : public Program { public: ProgramRaster(Context *rsc, - Element *in, - Element *out, bool pointSmooth, bool lineSmooth, bool pointSprite); virtual ~ProgramRaster(); virtual void setupGL(const Context *, ProgramRasterState *); + virtual void setupGL2(const Context *, ProgramRasterState *); void setLineWidth(float w); void setPointSize(float s); diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp index 68f589f..28f13d4 100644 --- a/libs/rs/rsProgramVertex.cpp +++ b/libs/rs/rsProgramVertex.cpp @@ -19,18 +19,34 @@ #include <GLES/gl.h> #include <GLES/glext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> using namespace android; using namespace android::renderscript; -ProgramVertex::ProgramVertex(Context *rsc, Element *in, Element *out) : - Program(rsc, in, out) +ProgramVertex::ProgramVertex(Context *rsc, bool texMat) : + Program(rsc) +{ + mAllocFile = __FILE__; + mAllocLine = __LINE__; + mTextureMatrixEnable = texMat; + mLightCount = 0; + init(rsc); +} + +ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText, + uint32_t shaderLength, const uint32_t * params, + uint32_t paramLength) : + Program(rsc, shaderText, shaderLength, params, paramLength) { mAllocFile = __FILE__; mAllocLine = __LINE__; mTextureMatrixEnable = false; mLightCount = 0; + + init(rsc); } ProgramVertex::~ProgramVertex() @@ -40,10 +56,10 @@ ProgramVertex::~ProgramVertex() static void logMatrix(const char *txt, const float *f) { LOGV("Matrix %s, %p", txt, f); - LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[0], f[4], f[8], f[12]); - LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[1], f[5], f[9], f[13]); - LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[2], f[6], f[10], f[14]); - LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[3], f[7], f[11], f[15]); + LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[0], f[4], f[8], f[12]); + LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[1], f[5], f[9], f[13]); + LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[2], f[6], f[10], f[14]); + LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[3], f[7], f[11], f[15]); } void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state) @@ -53,7 +69,7 @@ void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state) } state->mLast.set(this); - const float *f = static_cast<const float *>(mConstants->getPtr()); + const float *f = static_cast<const float *>(mConstants[0]->getPtr()); glMatrixMode(GL_TEXTURE); if (mTextureMatrixEnable) { @@ -92,6 +108,172 @@ void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state) mDirty = false; } +void ProgramVertex::loadShader(Context *rsc) { + Program::loadShader(rsc, GL_VERTEX_SHADER); +} + +void ProgramVertex::createShader() +{ + mShader.setTo(""); + + mShader.append("varying vec4 varColor;\n"); + mShader.append("varying vec4 varTex0;\n"); + + if (mUserShader.length() > 1) { + mShader.append("uniform mat4 "); + mShader.append(mUniformNames[0]); + mShader.append(";\n"); + + for (uint32_t ct=0; ct < mConstantCount; ct++) { + const Element *e = mConstantTypes[ct]->getElement(); + for (uint32_t field=0; field < e->getFieldCount(); field++) { + const Element *f = e->getField(field); + + // Cannot be complex + rsAssert(!f->getFieldCount()); + switch(f->getComponent().getVectorSize()) { + case 1: mShader.append("uniform float UNI_"); break; + case 2: mShader.append("uniform vec2 UNI_"); break; + case 3: mShader.append("uniform vec3 UNI_"); break; + case 4: mShader.append("uniform vec4 UNI_"); break; + default: + rsAssert(0); + } + + mShader.append(e->getFieldName(field)); + mShader.append(";\n"); + } + } + + + for (uint32_t ct=0; ct < mInputCount; ct++) { + const Element *e = mInputElements[ct].get(); + for (uint32_t field=0; field < e->getFieldCount(); field++) { + const Element *f = e->getField(field); + + // Cannot be complex + rsAssert(!f->getFieldCount()); + switch(f->getComponent().getVectorSize()) { + case 1: mShader.append("attribute float ATTRIB_"); break; + case 2: mShader.append("attribute vec2 ATTRIB_"); break; + case 3: mShader.append("attribute vec3 ATTRIB_"); break; + case 4: mShader.append("attribute vec4 ATTRIB_"); break; + default: + rsAssert(0); + } + + mShader.append(e->getFieldName(field)); + mShader.append(";\n"); + } + } + mShader.append(mUserShader); + } else { + mShader.append("attribute vec4 ATTRIB_LegacyPosition;\n"); + mShader.append("attribute vec4 ATTRIB_LegacyColor;\n"); + mShader.append("attribute vec3 ATTRIB_LegacyNormal;\n"); + mShader.append("attribute float ATTRIB_LegacyPointSize;\n"); + mShader.append("attribute vec4 ATTRIB_LegacyTexture;\n"); + + for (uint32_t ct=0; ct < mUniformCount; ct++) { + mShader.append("uniform mat4 "); + mShader.append(mUniformNames[ct]); + mShader.append(";\n"); + } + + mShader.append("void main() {\n"); + mShader.append(" gl_Position = UNI_MVP * ATTRIB_LegacyPosition;\n"); + mShader.append(" gl_PointSize = ATTRIB_LegacyPointSize;\n"); + + mShader.append(" varColor = ATTRIB_LegacyColor;\n"); + if (mTextureMatrixEnable) { + mShader.append(" varTex0 = UNI_TexMatrix * ATTRIB_LegacyTexture;\n"); + } else { + mShader.append(" varTex0 = ATTRIB_LegacyTexture;\n"); + } + //mShader.append(" pos.x = pos.x / 480.0;\n"); + //mShader.append(" pos.y = pos.y / 800.0;\n"); + //mShader.append(" gl_Position = pos;\n"); + mShader.append("}\n"); + } +} + +void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, ShaderCache *sc) +{ + //LOGE("sgl2 vtx1 %x", glGetError()); + if ((state->mLast.get() == this) && !mDirty) { + //return; + } + + rsc->checkError("ProgramVertex::setupGL2 start"); + glVertexAttrib4f(1, state->color[0], state->color[1], state->color[2], state->color[3]); + + const float *f = static_cast<const float *>(mConstants[0]->getPtr()); + + Matrix mvp; + mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); + Matrix t; + t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]); + mvp.multiply(&t); + + glUniformMatrix4fv(sc->vtxUniformSlot(0), 1, GL_FALSE, mvp.m); + if (mTextureMatrixEnable) { + glUniformMatrix4fv(sc->vtxUniformSlot(1), 1, GL_FALSE, + &f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]); + } + + rsc->checkError("ProgramVertex::setupGL2 begin uniforms"); + uint32_t uidx = 1; + for (uint32_t ct=0; ct < mConstantCount; ct++) { + Allocation *alloc = mConstants[ct+1].get(); + if (!alloc) { + continue; + } + + const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr()); + const Element *e = mConstantTypes[ct]->getElement(); + for (uint32_t field=0; field < e->getFieldCount(); field++) { + const Element *f = e->getField(field); + uint32_t offset = e->getFieldOffsetBytes(field); + int32_t slot = sc->vtxUniformSlot(uidx); + + const float *fd = reinterpret_cast<const float *>(&data[offset]); + + //LOGE("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i", slot, offset, ct, field, uidx); + if (slot >= 0) { + switch(f->getComponent().getVectorSize()) { + case 1: + //LOGE("Uniform 1 = %f", fd[0]); + glUniform1fv(slot, 1, fd); + break; + case 2: + //LOGE("Uniform 2 = %f %f", fd[0], fd[1]); + glUniform2fv(slot, 1, fd); + break; + case 3: + //LOGE("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]); + glUniform3fv(slot, 1, fd); + break; + case 4: + //LOGE("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]); + glUniform4fv(slot, 1, fd); + break; + default: + rsAssert(0); + } + } + uidx ++; + } + } + + for (uint32_t ct=0; ct < mConstantCount; ct++) { + uint32_t glSlot = sc->vtxUniformSlot(ct + 1); + + } + + state->mLast.set(this); + rsc->checkError("ProgramVertex::setupGL2"); +} + void ProgramVertex::addLight(const Light *l) { if (mLightCount < MAX_LIGHTS) { @@ -102,60 +284,103 @@ void ProgramVertex::addLight(const Light *l) void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const { - float *f = static_cast<float *>(mConstants->getPtr()); + float *f = static_cast<float *>(mConstants[0]->getPtr()); memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix)); mDirty = true; } void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const { - float *f = static_cast<float *>(mConstants->getPtr()); + float *f = static_cast<float *>(mConstants[0]->getPtr()); memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix)); mDirty = true; } void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const { - float *f = static_cast<float *>(mConstants->getPtr()); + float *f = static_cast<float *>(mConstants[0]->getPtr()); memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix)); mDirty = true; } void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const float *v3in) const { - float *f = static_cast<float *>(mConstants->getPtr()); + float *f = static_cast<float *>(mConstants[0]->getPtr()); Matrix mvp; mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], (Matrix *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); mvp.vectorMultiply(v4out, v3in); } +void ProgramVertex::initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix) +{ + rsAssert(e->getFieldCount()); + for (uint32_t ct=0; ct < e->getFieldCount(); ct++) { + const Element *ce = e->getField(ct); + if (ce->getFieldCount()) { + initAddUserElement(ce, names, count, prefix); + } else { + String8 tmp(prefix); + tmp.append(e->getFieldName(ct)); + names[*count].setTo(tmp.string()); + (*count)++; + } + } +} + + +void ProgramVertex::init(Context *rsc) +{ + mAttribCount = 0; + if (mUserShader.size() > 0) { + for (uint32_t ct=0; ct < mInputCount; ct++) { + initAddUserElement(mInputElements[ct].get(), mAttribNames, &mAttribCount, "ATTRIB_"); + } + + mUniformCount = 1; + mUniformNames[0].setTo("UNI_MVP"); + for (uint32_t ct=0; ct < mConstantCount; ct++) { + initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_"); + } + } else { + mUniformCount = 2; + mUniformNames[0].setTo("UNI_MVP"); + mUniformNames[1].setTo("UNI_TexMatrix"); + } + + createShader(); +} + + +/////////////////////////////////////////////////////////////////////// + ProgramVertexState::ProgramVertexState() { - mPV = NULL; } ProgramVertexState::~ProgramVertexState() { - delete mPV; } void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h) { - rsi_ElementBegin(rsc); - rsi_ElementAdd(rsc, RS_KIND_USER, RS_TYPE_FLOAT, false, 32, NULL); - RsElement e = rsi_ElementCreate(rsc); + RsElement e = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1); rsi_TypeBegin(rsc, e); rsi_TypeAdd(rsc, RS_DIMENSION_X, 48); mAllocType.set((Type *)rsi_TypeCreate(rsc)); - ProgramVertex *pv = new ProgramVertex(rsc, NULL, NULL); + ProgramVertex *pv = new ProgramVertex(rsc, false); Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType.get()); mDefaultAlloc.set(alloc); mDefault.set(pv); + pv->init(rsc); + pv->bindAllocation(alloc, 0); - pv->bindAllocation(alloc); + color[0] = 1.f; + color[1] = 1.f; + color[2] = 1.f; + color[3] = 1.f; updateSize(rsc, w, h); } @@ -176,42 +401,27 @@ void ProgramVertexState::deinit(Context *rsc) mDefault.clear(); mAllocType.clear(); mLast.clear(); - delete mPV; - mPV = NULL; } namespace android { namespace renderscript { -void rsi_ProgramVertexBegin(Context *rsc, RsElement in, RsElement out) -{ - delete rsc->mStateVertex.mPV; - rsc->mStateVertex.mPV = new ProgramVertex(rsc, (Element *)in, (Element *)out); -} -RsProgramVertex rsi_ProgramVertexCreate(Context *rsc) +RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, bool texMat) { - ProgramVertex *pv = rsc->mStateVertex.mPV; + ProgramVertex *pv = new ProgramVertex(rsc, texMat); pv->incUserRef(); - rsc->mStateVertex.mPV = 0; return pv; } -void rsi_ProgramVertexBindAllocation(Context *rsc, RsProgramVertex vpgm, RsAllocation constants) +RsProgramVertex rsi_ProgramVertexCreate2(Context *rsc, const char * shaderText, + uint32_t shaderLength, const uint32_t * params, + uint32_t paramLength) { - ProgramVertex *pv = static_cast<ProgramVertex *>(vpgm); - pv->bindAllocation(static_cast<Allocation *>(constants)); -} - -void rsi_ProgramVertexSetTextureMatrixEnable(Context *rsc, bool enable) -{ - rsc->mStateVertex.mPV->setTextureMatrixEnable(enable); -} - -void rsi_ProgramVertexAddLight(Context *rsc, RsLight light) -{ - rsc->mStateVertex.mPV->addLight(static_cast<const Light *>(light)); + ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, params, paramLength); + pv->incUserRef(); + return pv; } diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h index a97ba38..28554cc 100644 --- a/libs/rs/rsProgramVertex.h +++ b/libs/rs/rsProgramVertex.h @@ -30,10 +30,13 @@ class ProgramVertex : public Program public: const static uint32_t MAX_LIGHTS = 8; - ProgramVertex(Context *, Element *in, Element *out); + ProgramVertex(Context *,const char * shaderText, uint32_t shaderLength, + const uint32_t * params, uint32_t paramLength); + ProgramVertex(Context *, bool texMat); virtual ~ProgramVertex(); virtual void setupGL(const Context *rsc, ProgramVertexState *state); + virtual void setupGL2(const Context *rsc, ProgramVertexState *state, ShaderCache *sc); void setTextureMatrixEnable(bool e) {mTextureMatrixEnable = e;} @@ -45,6 +48,10 @@ public: void transformToScreen(const Context *, float *v4out, const float *v3in) const; + virtual void createShader(); + virtual void loadShader(Context *); + virtual void init(Context *); + protected: uint32_t mLightCount; @@ -52,6 +59,9 @@ protected: // Hacks to create a program for now bool mTextureMatrixEnable; + +private: + void initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix); }; @@ -71,11 +81,8 @@ public: ObjectBaseRef<Type> mAllocType; - ProgramVertex *mPV; - - //ObjectBaseRef<Type> mTextureTypes[ProgramFragment::MAX_TEXTURE]; - + float color[4]; }; diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp index b793750..7552d54 100644 --- a/libs/rs/rsSampler.cpp +++ b/libs/rs/rsSampler.cpp @@ -53,7 +53,7 @@ Sampler::~Sampler() { } -void Sampler::setupGL() +void Sampler::setupGL(const Context *rsc) { GLenum trans[] = { GL_NEAREST, //RS_SAMPLER_NEAREST, @@ -64,12 +64,12 @@ void Sampler::setupGL() }; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, trans[mMagFilter]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, trans[mWrapS]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, trans[mWrapT]); + rsc->checkError("ProgramFragment::setupGL2 tex env"); } void Sampler::bindToContext(SamplerState *ss, uint32_t slot) @@ -84,18 +84,18 @@ void Sampler::unbindFromContext(SamplerState *ss) mBoundSlot = -1; ss->mSamplers[slot].clear(); } - +/* void SamplerState::setupGL() { for (uint32_t ct=0; ct < RS_MAX_SAMPLER_SLOT; ct++) { Sampler *s = mSamplers[ct].get(); if (s) { - s->setupGL(); + s->setupGL(rsc); } else { glBindTexture(GL_TEXTURE_2D, 0); } } -} +}*/ //////////////////////////////// diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h index ccf9b4d..9e20a2f 100644 --- a/libs/rs/rsSampler.h +++ b/libs/rs/rsSampler.h @@ -41,7 +41,7 @@ public: virtual ~Sampler(); void bind(Allocation *); - void setupGL(); + void setupGL(const Context *); void bindToContext(SamplerState *, uint32_t slot); void unbindFromContext(SamplerState *); @@ -74,7 +74,7 @@ public: ObjectBaseRef<Sampler> mSamplers[RS_MAX_SAMPLER_SLOT]; - void setupGL(); + //void setupGL(); }; diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp index f11b862..b7e0b86 100644 --- a/libs/rs/rsScriptC.cpp +++ b/libs/rs/rsScriptC.cpp @@ -137,7 +137,6 @@ void ScriptCState::runCompiler(Context *rsc, ScriptC *s) rsc->appendNameDefines(&tmp); appendDecls(&tmp); - rsc->appendVarDefines(&tmp); appendVarDefines(rsc, &tmp); appendTypes(rsc, &tmp); tmp.append("#line 1\n"); @@ -270,12 +269,12 @@ void ScriptCState::runCompiler(Context *rsc, ScriptC *s) static void appendElementBody(String8 *s, const Element *e) { s->append(" {\n"); - for (size_t ct2=0; ct2 < e->getComponentCount(); ct2++) { - const Component *c = e->getComponent(ct2); + for (size_t ct2=0; ct2 < e->getFieldCount(); ct2++) { + const Element *c = e->getField(ct2); s->append(" "); s->append(c->getCType()); s->append(" "); - s->append(c->getComponentName()); + s->append(e->getFieldName(ct2)); s->append(";\n"); } s->append("}"); @@ -311,9 +310,15 @@ void ScriptCState::appendTypes(const Context *rsc, String8 *str) char buf[256]; String8 tmp; - str->append("struct vec2_s {float x; float y;};"); - str->append("struct vec3_s {float x; float y; float z;};"); - str->append("struct vec4_s {float x; float y; float z; float w;};"); + str->append("struct vecF32_2_s {float x; float y;};\n"); + str->append("struct vecF32_3_s {float x; float y; float z;};\n"); + str->append("struct vecF32_4_s {float x; float y; float z; float w;};\n"); + str->append("struct vecU8_4_s {char r; char g; char b; char a;};\n"); + str->append("#define vecF32_2_t struct vecF32_2_s\n"); + str->append("#define vecF32_3_t struct vecF32_3_s\n"); + str->append("#define vecF32_4_t struct vecF32_4_s\n"); + str->append("#define vecU8_4_t struct vecU8_4_s\n"); + str->append("#define vecI8_4_t struct vecU8_4_s\n"); for (size_t ct=0; ct < MAX_SCRIPT_BANKS; ct++) { const Type *t = mConstantBufferTypes[ct].get(); @@ -321,11 +326,12 @@ void ScriptCState::appendTypes(const Context *rsc, String8 *str) continue; } const Element *e = t->getElement(); - if (e->getName() && (e->getComponentCount() > 1)) { + if (e->getName() && (e->getFieldCount() > 1)) { String8 s("struct struct_"); s.append(e->getName()); - appendElementBody(&s, e); + s.append(e->getCStructBody()); s.append(";\n"); + s.append("#define "); s.append(e->getName()); s.append("_t struct struct_"); @@ -337,45 +343,25 @@ void ScriptCState::appendTypes(const Context *rsc, String8 *str) str->append(s); } - if (t->getName()) { - for (size_t ct2=0; ct2 < e->getComponentCount(); ct2++) { - const Component *c = e->getComponent(ct2); - tmp.setTo("#define OFFSETOF_"); - tmp.append(t->getName()); - tmp.append("_"); - tmp.append(c->getComponentName()); - sprintf(buf, " %i\n", ct2); - tmp.append(buf); - if (rsc->props.mLogScripts) { - LOGV(tmp); - } - str->append(tmp); - } - } - if (mSlotNames[ct].length() > 0) { String8 s; - if (e->getComponentCount() > 1) { - if (e->getName()) { - // Use the named struct - s.setTo(e->getName()); - s.append("_t *"); - } else { - // create an struct named from the slot. - s.setTo("struct "); - s.append(mSlotNames[ct]); - s.append("_s"); - appendElementBody(&s, e); - s.append(";\n"); - s.append("struct "); - s.append(mSlotNames[ct]); - s.append("_s * "); - } + if (e->getName()) { + // Use the named struct + s.setTo(e->getName()); } else { - // Just make an array - s.setTo(e->getComponent(0)->getCType()); - s.append("_t *"); + // create an struct named from the slot. + s.setTo("struct "); + s.append(mSlotNames[ct]); + s.append("_s"); + s.append(e->getCStructBody()); + //appendElementBody(&s, e); + s.append(";\n"); + s.append("struct "); + s.append(mSlotNames[ct]); + s.append("_s"); } + + s.append(" * "); s.append(mSlotNames[ct]); s.append(";\n"); if (rsc->props.mLogScripts) { diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp index de8df39..61bb16f 100644 --- a/libs/rs/rsScriptC_Lib.cpp +++ b/libs/rs/rsScriptC_Lib.cpp @@ -26,6 +26,8 @@ #include <GLES/gl.h> #include <GLES/glext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> #include <time.h> @@ -102,8 +104,9 @@ static float* SC_loadSimpleMeshVerticesF(RsSimpleMesh mesh, uint32_t idx) static void SC_updateSimpleMesh(RsSimpleMesh mesh) { + GET_TLS(); SimpleMesh *sm = static_cast<SimpleMesh *>(mesh); - sm->uploadAll(); + sm->uploadAll(rsc); } static uint32_t SC_loadU32(uint32_t bank, uint32_t offset) @@ -616,20 +619,20 @@ static void SC_vec2Rand(float *vec, float maxLen) static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va) { GET_TLS(); - rsi_ProgramFragmentBindTexture(rsc, - static_cast<ProgramFragment *>(vpf), - slot, - static_cast<Allocation *>(va)); + rsi_ProgramBindTexture(rsc, + static_cast<ProgramFragment *>(vpf), + slot, + static_cast<Allocation *>(va)); } static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs) { GET_TLS(); - rsi_ProgramFragmentBindSampler(rsc, - static_cast<ProgramFragment *>(vpf), - slot, - static_cast<Sampler *>(vs)); + rsi_ProgramBindSampler(rsc, + static_cast<ProgramFragment *>(vpf), + slot, + static_cast<Sampler *>(vs)); } @@ -683,13 +686,13 @@ static void SC_drawLine(float x1, float y1, float z1, rsc->setupCheck(); float vtx[] = { x1, y1, z1, x2, y2, z2 }; - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vtx); - - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); + VertexArray va; + va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx); + if (rsc->checkVersion2_0()) { + va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache); + } else { + va.setupGL(rsc, &rsc->mStateVertexArray); + } glDrawArrays(GL_LINES, 0, 2); } @@ -701,12 +704,13 @@ static void SC_drawPoint(float x, float y, float z) float vtx[] = { x, y, z }; - glBindBuffer(GL_ARRAY_BUFFER, 0); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vtx); - - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); + VertexArray va; + va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx); + if (rsc->checkVersion2_0()) { + va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache); + } else { + va.setupGL(rsc, &rsc->mStateVertexArray); + } glDrawArrays(GL_POINTS, 0, 1); } @@ -721,6 +725,7 @@ static void SC_drawQuadTexCoords(float x1, float y1, float z1, float u4, float v4) { GET_TLS(); + rsc->setupCheck(); //LOGE("Quad"); //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1); @@ -731,26 +736,15 @@ static void SC_drawQuadTexCoords(float x1, float y1, float z1, float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4}; const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4}; - rsc->setupCheck(); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vtx); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, tex); - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, tex); - glClientActiveTexture(GL_TEXTURE0); - - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); + VertexArray va; + va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx); + va.addLegacy(GL_FLOAT, 2, 8, RS_KIND_TEXTURE, false, (uint32_t)tex); + if (rsc->checkVersion2_0()) { + va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache); + } else { + va.setupGL(rsc, &rsc->mStateVertexArray); + } - //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } @@ -769,29 +763,46 @@ static void SC_drawQuad(float x1, float y1, float z1, static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h) { GET_TLS(); - rsc->setupCheck(); + ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex()); + rsc->setVertex(rsc->getDefaultProgramVertex()); + //rsc->setupCheck(); + + //GLint crop[4] = {0, h, w, -h}; + + float sh = rsc->getHeight(); - GLint crop[4] = {0, h, w, -h}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); - glDrawTexfOES(x, y, z, w, h); + SC_drawQuad(x, sh - y, z, + x+w, sh - y, z, + x+w, sh - (y+h), z, + x, sh - (y+h), z); + rsc->setVertex((ProgramVertex *)tmp.get()); } static void SC_drawSpriteScreenspaceCropped(float x, float y, float z, float w, float h, float cx0, float cy0, float cx1, float cy1) { GET_TLS(); - rsc->setupCheck(); + ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex()); + rsc->setVertex(rsc->getDefaultProgramVertex()); + + float tw = rsc->getFragment()->getTexture(0)->getType()->getDimY(); + float th = rsc->getFragment()->getTexture(0)->getType()->getDimX(); + float sh = rsc->getHeight(); + float u0 = cx0 / tw; + float u1 = (cx1 + cx0) / tw; + float v0 = cy0 / th; + float v1 = (cy1 + cy0) / th; - GLint crop[4] = {cx0, cy0, cx1, cy1}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); - glDrawTexfOES(x, y, z, w, h); + SC_drawQuadTexCoords(x, sh - y, z, u0, v0, + x+w, sh - y, z, u1, v0, + x+w, sh - (y+h), z, u1, v1, + x, sh - (y+h), z, u0, v1); + rsc->setVertex((ProgramVertex *)tmp.get()); } static void SC_drawSprite(float x, float y, float z, float w, float h) { GET_TLS(); - rsc->setupCheck(); - float vin[3] = {x, y, z}; float vout[4]; @@ -813,9 +824,8 @@ static void SC_drawSprite(float x, float y, float z, float w, float h) //LOGE("ds out2 %f %f %f", vout[0], vout[1], vout[2]); // U, V, W, H - GLint crop[4] = {0, h, w, -h}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); - glDrawTexiOES(vout[0], vout[1], 0/*vout[2]*/, w, h); + SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w); + //rsc->setupCheck(); } @@ -833,7 +843,7 @@ static void SC_drawSimpleMesh(RsSimpleMesh vsm) GET_TLS(); SimpleMesh *sm = static_cast<SimpleMesh *>(vsm); rsc->setupCheck(); - sm->render(); + sm->render(rsc); } static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len) @@ -841,7 +851,7 @@ static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t le GET_TLS(); SimpleMesh *sm = static_cast<SimpleMesh *>(vsm); rsc->setupCheck(); - sm->renderRange(start, len); + sm->renderRange(rsc, start, len); } @@ -851,7 +861,14 @@ static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t le static void SC_color(float r, float g, float b, float a) { - glColor4f(r, g, b, a); + GET_TLS(); + rsc->mStateVertex.color[0] = r; + rsc->mStateVertex.color[1] = g; + rsc->mStateVertex.color[2] = b; + rsc->mStateVertex.color[3] = a; + if (!rsc->checkVersion2_0()) { + glColor4f(r, g, b, a); + } } static void SC_ambient(float r, float g, float b, float a) @@ -956,9 +973,14 @@ static int SC_hsbToAbgr(float h, float s, float b, float a) static void SC_hsb(float h, float s, float b, float a) { + GET_TLS(); float rgb[3]; SC_hsbToRgb(h, s, b, rgb); - glColor4f(rgb[0], rgb[1], rgb[2], a); + if (rsc->checkVersion2_0()) { + glVertexAttrib4f(1, rgb[0], rgb[1], rgb[2], a); + } else { + glColor4f(rgb[0], rgb[1], rgb[2], a); + } } static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel) @@ -973,6 +995,13 @@ static void SC_uploadToBufferObject(RsAllocation va) rsi_AllocationUploadToBufferObject(rsc, va); } +static void SC_syncToGL(RsAllocation va) +{ + GET_TLS(); + Allocation *a = static_cast<Allocation *>(va); + +} + static void SC_ClearColor(float r, float g, float b, float a) { //LOGE("c %f %f %f %f", r, g, b, a); @@ -1221,33 +1250,33 @@ ScriptCState::SymbolTable_t ScriptCState::gSyms[] = { // vec3 { "vec3Norm", (void *)&SC_vec3Norm, - "void", "(struct vec3_s *)" }, + "void", "(struct vecF32_3_s *)" }, { "vec3Length", (void *)&SC_vec3Length, - "float", "(struct vec3_s *)" }, + "float", "(struct vecF32_3_s *)" }, { "vec3Add", (void *)&SC_vec3Add, - "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" }, + "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" }, { "vec3Sub", (void *)&SC_vec3Sub, - "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" }, + "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" }, { "vec3Cross", (void *)&SC_vec3Cross, - "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" }, + "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" }, { "vec3Dot", (void *)&SC_vec3Dot, - "float", "(struct vec3_s *lhs, struct vec3_s *rhs)" }, + "float", "(struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" }, { "vec3Scale", (void *)&SC_vec3Scale, - "void", "(struct vec3_s *lhs, float scale)" }, + "void", "(struct vecF32_3_s *lhs, float scale)" }, // vec4 { "vec4Norm", (void *)&SC_vec4Norm, - "void", "(struct vec4_s *)" }, + "void", "(struct vecF32_4_s *)" }, { "vec4Length", (void *)&SC_vec4Length, - "float", "(struct vec4_s *)" }, + "float", "(struct vecF32_4_s *)" }, { "vec4Add", (void *)&SC_vec4Add, - "void", "(struct vec4_s *dest, struct vec4_s *lhs, struct vec4_s *rhs)" }, + "void", "(struct vecF32_4_s *dest, struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" }, { "vec4Sub", (void *)&SC_vec4Sub, - "void", "(struct vec4_s *dest, struct vec4_s *lhs, struct vec4_s *rhs)" }, + "void", "(struct vecF32_4_s *dest, struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" }, { "vec4Dot", (void *)&SC_vec4Dot, - "float", "(struct vec4_s *lhs, struct vec4_s *rhs)" }, + "float", "(struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" }, { "vec4Scale", (void *)&SC_vec4Scale, - "void", "(struct vec4_s *lhs, float scale)" }, + "void", "(struct vecF32_4_s *lhs, float scale)" }, // context { "bindProgramFragment", (void *)&SC_bindProgramFragment, @@ -1323,6 +1352,9 @@ ScriptCState::SymbolTable_t ScriptCState::gSyms[] = { { "uploadToBufferObject", (void *)&SC_uploadToBufferObject, "void", "(int)" }, + { "syncToGL", (void *)&SC_syncToGL, + "void", "(int)" }, + { "colorFloatRGBAtoUNorm8", (void *)&SC_colorFloatRGBAtoUNorm8, "int", "(float, float, float, float)" }, { "colorFloatRGBto565", (void *)&SC_colorFloatRGBAto565, diff --git a/libs/rs/rsShaderCache.cpp b/libs/rs/rsShaderCache.cpp new file mode 100644 index 0000000..3a1f370 --- /dev/null +++ b/libs/rs/rsShaderCache.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rsContext.h" + +#include <GLES/gl.h> +#include <GLES2/gl2.h> + +using namespace android; +using namespace android::renderscript; + + +ShaderCache::ShaderCache() +{ + mEntryCount = 0; + mEntryAllocationCount = 16; + mEntries = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t)); +} + +ShaderCache::~ShaderCache() +{ + for (uint32_t ct=0; ct < mEntryCount; ct++) { + glDeleteProgram(mEntries[ct].program); + } + + mEntryCount = 0; + mEntryAllocationCount = 0; + free(mEntries); +} + +bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag) +{ + if (!vtx->getShaderID()) { + vtx->loadShader(rsc); + } + if (!frag->getShaderID()) { + frag->loadShader(rsc); + } + //LOGV("ShaderCache lookup vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID()); + + for (uint32_t ct=0; ct < mEntryCount; ct++) { + if ((mEntries[ct].vtx == vtx->getShaderID()) && + (mEntries[ct].frag == frag->getShaderID())) { + + //LOGV("SC using program %i", mEntries[ct].program); + glUseProgram(mEntries[ct].program); + mCurrent = &mEntries[ct]; + //LOGV("ShaderCache hit, using %i", ct); + rsc->checkError("ShaderCache::lookup (hit)"); + return true; + } + } + // Not in cache, add it. + + if (mEntryAllocationCount == mEntryCount) { + // Out of space, make some. + mEntryAllocationCount *= 2; + entry_t *e = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t)); + if (!e) { + LOGE("Out of memory for ShaderCache::lookup"); + return false; + } + memcpy(e, mEntries, sizeof(entry_t) * mEntryCount); + free(mEntries); + mEntries = e; + } + + //LOGV("ShaderCache miss, using %i", mEntryCount); + //LOGE("e0 %x", glGetError()); + + entry_t *e = &mEntries[mEntryCount]; + mCurrent = e; + e->vtx = vtx->getShaderID(); + e->frag = frag->getShaderID(); + e->program = glCreateProgram(); + e->mUserVertexProgram = vtx->isUserProgram(); + if (mEntries[mEntryCount].program) { + GLuint pgm = e->program; + glAttachShader(pgm, vtx->getShaderID()); + //LOGE("e1 %x", glGetError()); + glAttachShader(pgm, frag->getShaderID()); + + if (!vtx->isUserProgram()) { + glBindAttribLocation(pgm, 0, "ATTRIB_LegacyPosition"); + glBindAttribLocation(pgm, 1, "ATTRIB_LegacyColor"); + glBindAttribLocation(pgm, 2, "ATTRIB_LegacyNormal"); + glBindAttribLocation(pgm, 3, "ATTRIB_LegacyPointSize"); + glBindAttribLocation(pgm, 4, "ATTRIB_LegacyTexture"); + e->mVtxAttribSlots[RS_KIND_POSITION] = 0; + e->mVtxAttribSlots[RS_KIND_COLOR] = 1; + e->mVtxAttribSlots[RS_KIND_NORMAL] = 2; + e->mVtxAttribSlots[RS_KIND_POINT_SIZE] = 3; + e->mVtxAttribSlots[RS_KIND_TEXTURE] = 4; + } + + //LOGE("e2 %x", glGetError()); + glLinkProgram(pgm); + //LOGE("e3 %x", glGetError()); + GLint linkStatus = GL_FALSE; + glGetProgramiv(pgm, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + GLint bufLength = 0; + glGetProgramiv(pgm, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char* buf = (char*) malloc(bufLength); + if (buf) { + glGetProgramInfoLog(pgm, bufLength, NULL, buf); + LOGE("Could not link program:\n%s\n", buf); + free(buf); + } + } + glDeleteProgram(pgm); + } + if (vtx->isUserProgram()) { + for (uint32_t ct=0; ct < vtx->getAttribCount(); ct++) { + e->mVtxAttribSlots[ct] = glGetAttribLocation(pgm, vtx->getAttribName(ct)); + if (rsc->props.mLogShaders) { + LOGV("vtx A %i, %s = %d\n", ct, vtx->getAttribName(ct).string(), e->mVtxAttribSlots[ct]); + } + } + } + for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) { + e->mVtxUniformSlots[ct] = glGetUniformLocation(pgm, vtx->getUniformName(ct)); + if (rsc->props.mLogShaders) { + LOGV("vtx U, %s = %d\n", vtx->getUniformName(ct).string(), e->mVtxUniformSlots[ct]); + } + } + for (uint32_t ct=0; ct < frag->getUniformCount(); ct++) { + e->mFragUniformSlots[ct] = glGetUniformLocation(pgm, frag->getUniformName(ct)); + if (rsc->props.mLogShaders) { + LOGV("frag U, %s = %d\n", frag->getUniformName(ct).string(), e->mFragUniformSlots[ct]); + } + } + } + + //LOGV("SC made program %i", e->program); + glUseProgram(e->program); + mEntryCount++; + rsc->checkError("ShaderCache::lookup (miss)"); + return true; +} + +void ShaderCache::cleanupVertex(uint32_t id) +{ +} + +void ShaderCache::cleanupFragment(uint32_t id) +{ +} + +void ShaderCache::cleanupAll() +{ +} + diff --git a/libs/rs/rsShaderCache.h b/libs/rs/rsShaderCache.h new file mode 100644 index 0000000..7aa8183 --- /dev/null +++ b/libs/rs/rsShaderCache.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SHADER_CACHE_H +#define ANDROID_SHADER_CACHE_H + + +#include "rsObjectBase.h" +#include "rsVertexArray.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + +// An element is a group of Components that occupies one cell in a structure. +class ShaderCache +{ +public: + ShaderCache(); + virtual ~ShaderCache(); + + bool lookup(Context *rsc, ProgramVertex *, ProgramFragment *); + + void cleanupVertex(uint32_t id); + void cleanupFragment(uint32_t id); + + void cleanupAll(); + + int32_t vtxAttribSlot(uint32_t a) const {return mCurrent->mVtxAttribSlots[a];} + int32_t vtxUniformSlot(uint32_t a) const {return mCurrent->mVtxUniformSlots[a];} + int32_t fragAttribSlot(uint32_t a) const {return mCurrent->mFragAttribSlots[a];} + int32_t fragUniformSlot(uint32_t a) const {return mCurrent->mFragUniformSlots[a];} + bool isUserVertexProgram() const {return mCurrent->mUserVertexProgram;} + +protected: + typedef struct { + uint32_t vtx; + uint32_t frag; + uint32_t program; + int32_t mVtxAttribSlots[Program::MAX_ATTRIBS]; + int32_t mVtxUniformSlots[Program::MAX_UNIFORMS]; + int32_t mFragAttribSlots[Program::MAX_ATTRIBS]; + int32_t mFragUniformSlots[Program::MAX_UNIFORMS]; + bool mUserVertexProgram; + } entry_t; + entry_t *mEntries; + entry_t *mCurrent; + + uint32_t mEntryCount; + uint32_t mEntryAllocationCount; + +}; + + + +} +} +#endif //ANDROID_SHADER_CACHE_H + + + + diff --git a/libs/rs/rsSimpleMesh.cpp b/libs/rs/rsSimpleMesh.cpp index b082fd7..53ce5cd 100644 --- a/libs/rs/rsSimpleMesh.cpp +++ b/libs/rs/rsSimpleMesh.cpp @@ -34,62 +34,71 @@ SimpleMesh::~SimpleMesh() delete[] mVertexBuffers; } -void SimpleMesh::render() const +void SimpleMesh::render(Context *rsc) const { if (mPrimitiveType.get()) { - renderRange(0, mPrimitiveType->getDimX()); + renderRange(rsc, 0, mPrimitiveType->getDimX()); return; } if (mIndexType.get()) { - renderRange(0, mIndexType->getDimX()); + renderRange(rsc, 0, mIndexType->getDimX()); return; } - renderRange(0, mVertexTypes[0]->getDimX()); + renderRange(rsc, 0, mVertexTypes[0]->getDimX()); } -void SimpleMesh::renderRange(uint32_t start, uint32_t len) const +void SimpleMesh::renderRange(Context *rsc, uint32_t start, uint32_t len) const { if (len < 1) { return; } - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - for (uint32_t ct=0; ct < RS_MAX_TEXTURE; ct++) { - glClientActiveTexture(GL_TEXTURE0 + ct); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - glClientActiveTexture(GL_TEXTURE0); - - for (uint32_t ct=0; ct < mVertexTypeCount; ct++) { - glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[ct]->getBufferObjectID()); - mVertexTypes[ct]->enableGLVertexBuffer(); + rsc->checkError("SimpleMesh::renderRange 1"); + VertexArray va; + if (rsc->checkVersion2_0()) { + for (uint32_t ct=0; ct < mVertexTypeCount; ct++) { + mVertexBuffers[ct]->uploadCheck(rsc); + va.setActiveBuffer(mVertexBuffers[ct]->getBufferObjectID()); + mVertexTypes[ct]->enableGLVertexBuffer2(&va); + } + va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache); + } else { + for (uint32_t ct=0; ct < mVertexTypeCount; ct++) { + mVertexBuffers[ct]->uploadCheck(rsc); + va.setActiveBuffer(mVertexBuffers[ct]->getBufferObjectID()); + mVertexTypes[ct]->enableGLVertexBuffer(&va); + } + va.setupGL(rsc, 0); } + rsc->checkError("SimpleMesh::renderRange 2"); if (mIndexType.get()) { + mIndexBuffer->uploadCheck(rsc); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->getBufferObjectID()); glDrawElements(mGLPrimitive, len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2)); } else { glDrawArrays(mGLPrimitive, start, len); } + + rsc->checkError("SimpleMesh::renderRange"); } -void SimpleMesh::uploadAll() +void SimpleMesh::uploadAll(Context *rsc) { for (uint32_t ct=0; ct < mVertexTypeCount; ct++) { if (mVertexBuffers[ct].get()) { - mVertexBuffers[ct]->uploadToBufferObject(); + mVertexBuffers[ct]->deferedUploadToBufferObject(rsc); } } if (mIndexBuffer.get()) { - mIndexBuffer->uploadToBufferObject(); + mIndexBuffer->deferedUploadToBufferObject(rsc); } if (mPrimitiveBuffer.get()) { - mPrimitiveBuffer->uploadToBufferObject(); + mPrimitiveBuffer->deferedUploadToBufferObject(rsc); } + rsc->checkError("SimpleMesh::uploadAll"); } diff --git a/libs/rs/rsSimpleMesh.h b/libs/rs/rsSimpleMesh.h index 1e5c908..6defbda 100644 --- a/libs/rs/rsSimpleMesh.h +++ b/libs/rs/rsSimpleMesh.h @@ -45,9 +45,9 @@ public: uint32_t mGLPrimitive; - void render() const; - void renderRange(uint32_t start, uint32_t len) const; - void uploadAll(); + void render(Context *) const; + void renderRange(Context *, uint32_t start, uint32_t len) const; + void uploadAll(Context *); protected: diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp index ddaa2f0..22a267a 100644 --- a/libs/rs/rsType.cpp +++ b/libs/rs/rsType.cpp @@ -26,7 +26,6 @@ Type::Type(Context *rsc) : ObjectBase(rsc) mAllocLine = __LINE__; mLODs = 0; mLODCount = 0; - memset(&mGL, 0, sizeof(mGL)); clear(); } @@ -93,9 +92,9 @@ void Type::compute() mLODs[lod].mZ = tz; mLODs[lod].mOffset = offset; offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes(); - tx = (tx + 1) >> 1; - ty = (ty + 1) >> 1; - tz = (tz + 1) >> 1; + if (tx > 1) tx >>= 1; + if (ty > 1) ty >>= 1; + if (tz > 1) tz >>= 1; } // At this point the offset is the size of a mipmap chain; @@ -133,110 +132,64 @@ uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) co void Type::makeGLComponents() { - uint32_t texNum = 0; - memset(&mGL, 0, sizeof(mGL)); - - for (uint32_t ct=0; ct < getElement()->getComponentCount(); ct++) { - const Component *c = getElement()->getComponent(ct); + uint32_t userNum = 0; + + for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) { + const Component &c = getElement()->getField(ct)->getComponent(); + + switch(c.getKind()) { + case RS_KIND_USER: + mGL.mUser[userNum].size = c.getVectorSize(); + mGL.mUser[userNum].offset = mElement->getFieldOffsetBytes(ct); + mGL.mUser[userNum].type = c.getGLType(); + mGL.mUser[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized(); + mGL.mUser[userNum].name.setTo(getElement()->getFieldName(ct)); + userNum ++; + break; - switch(c->getKind()) { - case Component::X: + case RS_KIND_POSITION: rsAssert(mGL.mVtx.size == 0); - mGL.mVtx.size = 1; - mGL.mVtx.offset = mElement->getComponentOffsetBytes(ct); - mGL.mVtx.type = c->getGLType(); - break; - case Component::Y: - rsAssert(mGL.mVtx.size == 1); - rsAssert(mGL.mVtx.type == c->getGLType()); - mGL.mVtx.size = 2; - break; - case Component::Z: - rsAssert(mGL.mVtx.size == 2); - rsAssert(mGL.mVtx.type == c->getGLType()); - mGL.mVtx.size = 3; + mGL.mVtx.size = c.getVectorSize(); + mGL.mVtx.offset = mElement->getFieldOffsetBytes(ct); + mGL.mVtx.type = c.getGLType(); + mGL.mVtx.normalized = false; + mGL.mVtx.name.setTo("Position"); break; - case Component::W: - rsAssert(mGL.mVtx.size == 4); - rsAssert(mGL.mVtx.type == c->getGLType()); - mGL.mVtx.size = 4; - break; - case Component::RED: + case RS_KIND_COLOR: rsAssert(mGL.mColor.size == 0); - mGL.mColor.size = 1; - mGL.mColor.offset = mElement->getComponentOffsetBytes(ct); - mGL.mColor.type = c->getGLType(); - break; - case Component::GREEN: - rsAssert(mGL.mColor.size == 1); - rsAssert(mGL.mColor.type == c->getGLType()); - mGL.mColor.size = 2; - break; - case Component::BLUE: - rsAssert(mGL.mColor.size == 2); - rsAssert(mGL.mColor.type == c->getGLType()); - mGL.mColor.size = 3; + mGL.mColor.size = c.getVectorSize(); + mGL.mColor.offset = mElement->getFieldOffsetBytes(ct); + mGL.mColor.type = c.getGLType(); + mGL.mColor.normalized = c.getType() != RS_TYPE_FLOAT_32; + mGL.mColor.name.setTo("Color"); break; - case Component::ALPHA: - // Can be RGBA or A at this point - if (mGL.mColor.size > 0) { - rsAssert(mGL.mColor.size == 3); - rsAssert(mGL.mColor.type == c->getGLType()); - mGL.mColor.size = 4; - } else { - mGL.mColor.size = 1; - mGL.mColor.offset = mElement->getComponentOffsetBytes(ct); - mGL.mColor.type = c->getGLType(); - } - break; - case Component::NX: + case RS_KIND_NORMAL: rsAssert(mGL.mNorm.size == 0); - mGL.mNorm.size = 1; - mGL.mNorm.offset = mElement->getComponentOffsetBytes(ct); - mGL.mNorm.type = c->getGLType(); - break; - case Component::NY: - rsAssert(mGL.mNorm.size == 1); - rsAssert(mGL.mNorm.type == c->getGLType()); - mGL.mNorm.size = 2; - break; - case Component::NZ: - rsAssert(mGL.mNorm.size == 2); - rsAssert(mGL.mNorm.type == c->getGLType()); - mGL.mNorm.size = 3; - break; + mGL.mNorm.size = c.getVectorSize(); + mGL.mNorm.offset = mElement->getFieldOffsetBytes(ct); + mGL.mNorm.type = c.getGLType(); + mGL.mNorm.normalized = false; + mGL.mNorm.name.setTo("Normal"); + break; - case Component::S: - if (mGL.mTex[texNum].size) { - texNum++; - } - mGL.mTex[texNum].size = 1; - mGL.mTex[texNum].offset = mElement->getComponentOffsetBytes(ct); - mGL.mTex[texNum].type = c->getGLType(); - break; - case Component::T: - rsAssert(mGL.mTex[texNum].size == 1); - rsAssert(mGL.mTex[texNum].type == c->getGLType()); - mGL.mTex[texNum].size = 2; - break; - case Component::R: - rsAssert(mGL.mTex[texNum].size == 2); - rsAssert(mGL.mTex[texNum].type == c->getGLType()); - mGL.mTex[texNum].size = 3; - break; - case Component::Q: - rsAssert(mGL.mTex[texNum].size == 3); - rsAssert(mGL.mTex[texNum].type == c->getGLType()); - mGL.mTex[texNum].size = 4; - break; + case RS_KIND_TEXTURE: + rsAssert(mGL.mTex.size == 0); + mGL.mTex.size = c.getVectorSize(); + mGL.mTex.offset = mElement->getFieldOffsetBytes(ct); + mGL.mTex.type = c.getGLType(); + mGL.mTex.normalized = false; + mGL.mTex.name.setTo("Texture"); + break; - case Component::POINT_SIZE: + case RS_KIND_POINT_SIZE: rsAssert(!mGL.mPointSize.size); - mGL.mPointSize.size = 1; - mGL.mPointSize.offset = mElement->getComponentOffsetBytes(ct); - mGL.mPointSize.type = c->getGLType(); + mGL.mPointSize.size = c.getVectorSize(); + mGL.mPointSize.offset = mElement->getFieldOffsetBytes(ct); + mGL.mPointSize.type = c.getGLType(); + mGL.mPointSize.normalized = false; + mGL.mPointSize.name.setTo("PointSize"); break; default: @@ -245,62 +198,75 @@ void Type::makeGLComponents() } } -void Type::enableGLVertexBuffer() const +void Type::enableGLVertexBuffer(VertexArray *va) const { // Note: We are only going to enable buffers and never disable them - // here. The reasonis more than one Allocation may be used as a vertex + // here. The reason is more than one Allocation may be used as a vertex // source. So we cannot disable arrays that may have been in use by // another allocation. uint32_t stride = mElement->getSizeBytes(); if (mGL.mVtx.size) { - //LOGE("va vtx %i %x, %i, %p", mGL.mVtx.size, mGL.mVtx.type, stride, (void *)mGL.mVtx.offset); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(mGL.mVtx.size, - mGL.mVtx.type, - stride, - (void *)mGL.mVtx.offset); + va->addLegacy(mGL.mVtx.type, + mGL.mVtx.size, + stride, + RS_KIND_POSITION, + false, + mGL.mVtx.offset); } if (mGL.mNorm.size) { - //LOGE("va norm %i %x, %i, %p", mGL.mNorm.size, mGL.mNorm.type, stride, (void *)mGL.mNorm.offset); - glEnableClientState(GL_NORMAL_ARRAY); - rsAssert(mGL.mNorm.size == 3); - glNormalPointer(mGL.mNorm.type, - stride, - (void *)mGL.mNorm.offset); + va->addLegacy(mGL.mNorm.type, + 3, + stride, + RS_KIND_NORMAL, + false, + mGL.mNorm.offset); } if (mGL.mColor.size) { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(mGL.mColor.size, - mGL.mColor.type, - stride, - (void *)mGL.mColor.offset); + va->addLegacy(mGL.mColor.type, + mGL.mColor.size, + stride, + RS_KIND_COLOR, + true, + mGL.mColor.offset); } - for (uint32_t ct=0; ct < RS_MAX_TEXTURE; ct++) { - if (mGL.mTex[ct].size) { - //LOGE("va tex%i %i %x, %i, %p", ct, mGL.mTex[ct].size, mGL.mTex[ct].type, stride, (void *)mGL.mTex[ct].offset); - glClientActiveTexture(GL_TEXTURE0 + ct); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(mGL.mTex[ct].size, - mGL.mTex[ct].type, - stride, - (void *)mGL.mTex[ct].offset); - } + if (mGL.mTex.size) { + va->addLegacy(mGL.mTex.type, + mGL.mTex.size, + stride, + RS_KIND_TEXTURE, + false, + mGL.mTex.offset); } - glClientActiveTexture(GL_TEXTURE0); if (mGL.mPointSize.size) { - glEnableClientState(GL_POINT_SIZE_ARRAY_OES); - glPointSizePointerOES(mGL.mPointSize.type, - stride, - (void *)mGL.mPointSize.offset); + va->addLegacy(mGL.mPointSize.type, + 1, + stride, + RS_KIND_POINT_SIZE, + false, + mGL.mPointSize.offset); } } +void Type::enableGLVertexBuffer2(VertexArray *va) const +{ + // Do legacy buffers + enableGLVertexBuffer(va); + + uint32_t stride = mElement->getSizeBytes(); + for (uint32_t ct=0; ct < RS_MAX_ATTRIBS; ct++) { + if (mGL.mUser[ct].size) { + va->addUser(mGL.mUser[ct], stride); + } + } +} + + void Type::dumpLOGV(const char *prefix) const { diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h index 2c43405..4fa4933 100644 --- a/libs/rs/rsType.h +++ b/libs/rs/rsType.h @@ -18,6 +18,7 @@ #define ANDROID_STRUCTURED_TYPE_H #include "rsElement.h" +#include "rsVertexArray.h" // --------------------------------------------------------------------------- namespace android { @@ -67,7 +68,8 @@ public: void clear(); void compute(); - void enableGLVertexBuffer() const; + void enableGLVertexBuffer(class VertexArray *) const; + void enableGLVertexBuffer2(class VertexArray *) const; void dumpLOGV(const char *prefix) const; @@ -108,18 +110,13 @@ protected: LOD *mLODs; uint32_t mLODCount; - struct VertexComponent_t { - uint32_t offset; - uint32_t type; - uint32_t size; - uint32_t stride; - }; struct GLState_t { - VertexComponent_t mVtx; - VertexComponent_t mNorm; - VertexComponent_t mColor; - VertexComponent_t mTex[RS_MAX_TEXTURE]; - VertexComponent_t mPointSize; + VertexArray::Attrib mUser[RS_MAX_ATTRIBS]; + VertexArray::Attrib mVtx; + VertexArray::Attrib mNorm; + VertexArray::Attrib mColor; + VertexArray::Attrib mTex; + VertexArray::Attrib mPointSize; }; GLState_t mGL; void makeGLComponents(); diff --git a/libs/rs/rsVertexArray.cpp b/libs/rs/rsVertexArray.cpp new file mode 100644 index 0000000..d0c0414 --- /dev/null +++ b/libs/rs/rsVertexArray.cpp @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rsContext.h" + +#include <GLES/gl.h> +#include <GLES2/gl2.h> + +using namespace android; +using namespace android::renderscript; + + +VertexArray::VertexArray() +{ + clearAll(); +} + +VertexArray::~VertexArray() +{ +} + + +void VertexArray::clearAll() +{ + for (uint32_t ct=0; ct < RS_MAX_ATTRIBS; ct++) { + mAttribs[ct].clear(); + } + mActiveBuffer = 0; + mCount = 0; +} + +VertexArray::Attrib::Attrib() +{ + clear(); +} + +void VertexArray::Attrib::set(const Attrib &a) +{ + buffer = a.buffer; + offset = a.offset; + type = a.type; + size = a.size; + stride = a.stride; + normalized = a.normalized; + kind = RS_KIND_USER; + name.setTo(a.name); +} + +void VertexArray::Attrib::clear() +{ + buffer = 0; + offset = 0; + type = 0; + size = 0; + stride = 0; + normalized = false; + name.setTo(""); +} + +void VertexArray::clear(uint32_t n) +{ + mAttribs[n].clear(); +} + +void VertexArray::addUser(const Attrib &a, uint32_t stride) +{ + assert(mCount < RS_MAX_ATTRIBS); + mAttribs[mCount].set(a); + mAttribs[mCount].buffer = mActiveBuffer; + mAttribs[mCount].stride = stride; + mAttribs[mCount].kind = RS_KIND_USER; + mCount ++; +} + +void VertexArray::addLegacy(uint32_t type, uint32_t size, uint32_t stride, RsDataKind kind, bool normalized, uint32_t offset) +{ + assert(mCount < RS_MAX_ATTRIBS); + mAttribs[mCount].clear(); + mAttribs[mCount].type = type; + mAttribs[mCount].size = size; + mAttribs[mCount].offset = offset; + mAttribs[mCount].normalized = normalized; + mAttribs[mCount].buffer = mActiveBuffer; + mAttribs[mCount].stride = stride; + mAttribs[mCount].kind = kind; + mCount ++; +} + +void VertexArray::logAttrib(uint32_t idx, uint32_t slot) const { + LOGE("va %i: slot=%i name=%s buf=%i size=%i type=0x%x kind=%i stride=0x%x norm=%i offset=0x%x", idx, slot, + mAttribs[idx].name.string(), + mAttribs[idx].buffer, + mAttribs[idx].size, + mAttribs[idx].type, + mAttribs[idx].kind, + mAttribs[idx].stride, + mAttribs[idx].normalized, + mAttribs[idx].offset); +} + +void VertexArray::setupGL(const Context *rsc, class VertexArrayState *state) const +{ + glClientActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_POINT_SIZE_ARRAY_OES); + + for (uint32_t ct=0; ct < mCount; ct++) { + switch(mAttribs[ct].kind) { + case RS_KIND_POSITION: + //logAttrib(POSITION); + glEnableClientState(GL_VERTEX_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer); + glVertexPointer(mAttribs[ct].size, + mAttribs[ct].type, + mAttribs[ct].stride, + (void *)mAttribs[ct].offset); + break; + + case RS_KIND_NORMAL: + //logAttrib(NORMAL); + glEnableClientState(GL_NORMAL_ARRAY); + rsAssert(mAttribs[ct].size == 3); + glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer); + glNormalPointer(mAttribs[ct].type, + mAttribs[ct].stride, + (void *)mAttribs[ct].offset); + break; + + case RS_KIND_COLOR: + //logAttrib(COLOR); + glEnableClientState(GL_COLOR_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer); + glColorPointer(mAttribs[ct].size, + mAttribs[ct].type, + mAttribs[ct].stride, + (void *)mAttribs[ct].offset); + break; + + case RS_KIND_TEXTURE: + //logAttrib(TEXTURE); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer); + glTexCoordPointer(mAttribs[ct].size, + mAttribs[ct].type, + mAttribs[ct].stride, + (void *)mAttribs[ct].offset); + break; + + case RS_KIND_POINT_SIZE: + //logAttrib(POINT_SIZE); + glEnableClientState(GL_POINT_SIZE_ARRAY_OES); + glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer); + glPointSizePointerOES(mAttribs[ct].type, + mAttribs[ct].stride, + (void *)mAttribs[ct].offset); + break; + + default: + rsAssert(0); + } + } + + rsc->checkError("VertexArray::setupGL"); +} + +void VertexArray::setupGL2(const Context *rsc, class VertexArrayState *state, ShaderCache *sc) const +{ + rsc->checkError("VertexArray::setupGL2 start"); + for (uint32_t ct=1; ct <= state->mLastEnableCount; ct++) { + glDisableVertexAttribArray(ct); + } + + rsc->checkError("VertexArray::setupGL2 disabled"); + for (uint32_t ct=0; ct < mCount; ct++) { + uint32_t slot = 0; + if (sc->isUserVertexProgram()) { + slot = sc->vtxAttribSlot(ct); + } else { + slot = sc->vtxAttribSlot(mAttribs[ct].kind); + } + + //logAttrib(ct, slot); + glEnableVertexAttribArray(slot); + glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer); + + glVertexAttribPointer(slot, + mAttribs[ct].size, + mAttribs[ct].type, + mAttribs[ct].normalized, + mAttribs[ct].stride, + (void *)mAttribs[ct].offset); + } + state->mLastEnableCount = mCount; + rsc->checkError("VertexArray::setupGL2 done"); +} +//////////////////////////////////////////// + +void VertexArrayState::init(Context *) { + mLastEnableCount = 0; +} + diff --git a/libs/rs/rsVertexArray.h b/libs/rs/rsVertexArray.h new file mode 100644 index 0000000..3904cb6 --- /dev/null +++ b/libs/rs/rsVertexArray.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_VERTEX_ARRAY_H +#define ANDROID_VERTEX_ARRAY_H + + +#include "rsObjectBase.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + +class ShaderCache; + +// An element is a group of Components that occupies one cell in a structure. +class VertexArray +{ +public: + VertexArray(); + virtual ~VertexArray(); + + + class Attrib { + public: + uint32_t buffer; + uint32_t offset; + uint32_t type; + uint32_t size; + uint32_t stride; + bool normalized; + String8 name; + RsDataKind kind; + + Attrib(); + void set(const Attrib &); + void clear(); + }; + + + void clearAll(); + void setActiveBuffer(uint32_t id) {mActiveBuffer = id;} + void addUser(const Attrib &, uint32_t stride); + void addLegacy(uint32_t type, uint32_t size, uint32_t stride, RsDataKind kind, bool normalized, uint32_t offset); + + void setupGL(const Context *rsc, class VertexArrayState *) const; + void setupGL2(const Context *rsc, class VertexArrayState *, ShaderCache *) const; + void logAttrib(uint32_t idx, uint32_t slot) const; + +protected: + void clear(uint32_t index); + uint32_t mActiveBuffer; + uint32_t mCount; + + Attrib mAttribs[RS_MAX_ATTRIBS]; +}; + + +class VertexArrayState { +public: + void init(Context *); + + uint32_t mLastEnableCount; + //VertexArray::Attrib mAttribs[VertexArray::_LAST]; +}; + + +} +} +#endif //ANDROID_LIGHT_H + + + diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp index eda84ef..764e644 100644 --- a/libs/ui/SurfaceComposerClient.cpp +++ b/libs/ui/SurfaceComposerClient.cpp @@ -56,7 +56,7 @@ namespace android { // Must not be holding SurfaceComposerClient::mLock when acquiring gLock here. static Mutex gLock; static sp<ISurfaceComposer> gSurfaceManager; -static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections; +static DefaultKeyedVector< sp<IBinder>, wp<SurfaceComposerClient> > gActiveConnections; static SortedVector<sp<SurfaceComposerClient> > gOpenTransactions; static sp<IMemoryHeap> gServerCblkMemory; static volatile surface_flinger_cblk_t* gServerCblk; @@ -193,7 +193,7 @@ SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn) { // scope for lock Mutex::Autolock _l(gLock); - client = gActiveConnections.valueFor(conn); + client = gActiveConnections.valueFor(conn).promote(); } if (client == 0) { @@ -361,8 +361,8 @@ void SurfaceComposerClient::openGlobalTransaction() const size_t N = gActiveConnections.size(); VERBOSE("openGlobalTransaction (%ld clients)", N); for (size_t i=0; i<N; i++) { - sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i)); - if (gOpenTransactions.indexOf(client) < 0) { + sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i).promote()); + if (client != 0 && gOpenTransactions.indexOf(client) < 0) { if (client->openTransaction() == NO_ERROR) { if (gOpenTransactions.add(client) < 0) { // Ooops! diff --git a/location/java/android/location/Address.java b/location/java/android/location/Address.java index ac275c6..b152f48 100644 --- a/location/java/android/location/Address.java +++ b/location/java/android/location/Address.java @@ -500,7 +500,10 @@ public class Address implements Parcelable { a.mAdminArea = in.readString(); a.mSubAdminArea = in.readString(); a.mLocality = in.readString(); + a.mSubLocality = in.readString(); a.mThoroughfare = in.readString(); + a.mSubThoroughfare = in.readString(); + a.mPremises = in.readString(); a.mPostalCode = in.readString(); a.mCountryCode = in.readString(); a.mCountryName = in.readString(); @@ -544,7 +547,10 @@ public class Address implements Parcelable { parcel.writeString(mAdminArea); parcel.writeString(mSubAdminArea); parcel.writeString(mLocality); + parcel.writeString(mSubLocality); parcel.writeString(mThoroughfare); + parcel.writeString(mSubThoroughfare); + parcel.writeString(mPremises); parcel.writeString(mPostalCode); parcel.writeString(mCountryCode); parcel.writeString(mCountryName); diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java index 9233ea9..ed3fdde 100755 --- a/location/java/com/android/internal/location/GpsLocationProvider.java +++ b/location/java/com/android/internal/location/GpsLocationProvider.java @@ -805,29 +805,6 @@ public class GpsLocationProvider extends ILocationProvider.Stub { if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + " timestamp: " + timestamp); - mLastFixTime = System.currentTimeMillis(); - // report time to first fix - if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { - mTTFF = (int)(mLastFixTime - mFixRequestTime); - if (Config.LOGD) Log.d(TAG, "TTFF: " + mTTFF); - - // notify status listeners - synchronized(mListeners) { - int size = mListeners.size(); - for (int i = 0; i < size; i++) { - Listener listener = mListeners.get(i); - try { - listener.mListener.onFirstFix(mTTFF); - } catch (RemoteException e) { - Log.w(TAG, "RemoteException in stopNavigating"); - mListeners.remove(listener); - // adjust for size of list changing - size--; - } - } - } - } - synchronized (mLocation) { mLocationFlags = flags; if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { @@ -863,6 +840,29 @@ public class GpsLocationProvider extends ILocationProvider.Stub { } } + mLastFixTime = System.currentTimeMillis(); + // report time to first fix + if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { + mTTFF = (int)(mLastFixTime - mFixRequestTime); + if (Config.LOGD) Log.d(TAG, "TTFF: " + mTTFF); + + // notify status listeners + synchronized(mListeners) { + int size = mListeners.size(); + for (int i = 0; i < size; i++) { + Listener listener = mListeners.get(i); + try { + listener.mListener.onFirstFix(mTTFF); + } catch (RemoteException e) { + Log.w(TAG, "RemoteException in stopNavigating"); + mListeners.remove(listener); + // adjust for size of list changing + size--; + } + } + } + } + if (mStarted && mStatus != LocationProvider.AVAILABLE) { mAlarmManager.cancel(mTimeoutIntent); // send an intent to notify that the GPS is receiving fixes. diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 07542ed..f775ba0 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -132,7 +132,7 @@ import java.lang.ref.WeakReference; * <li>It is good programming practice to have your application * register a OnErrorListener to look out for error notifications from * the internal player engine.</li> - * <li>IlleglStateException is + * <li>IllegalStateException is * thrown to prevent programming errors such as calling {@link #prepare()}, * {@link #prepareAsync()}, or one of the overloaded <code>setDataSource * </code> methods in an invalid state. </li> diff --git a/media/libdrm/mobile2/Android.mk b/media/libdrm/mobile2/Android.mk index e187139..70c6683 100644 --- a/media/libdrm/mobile2/Android.mk +++ b/media/libdrm/mobile2/Android.mk @@ -74,6 +74,10 @@ LOCAL_MODULE := libdrm2 ifeq ($(TARGET_OS)-$(TARGET_ARCH),linux-x86) LOCAL_CFLAGS += -DUSTL_ANDROID_X86 +else + ifeq ($(TARGET_OS)-$(TARGET_ARCH),linux-sh) + LOCAL_CFLAGS += -DUSTL_ANDROID_SH + endif endif include $(BUILD_STATIC_LIBRARY) diff --git a/media/libdrm/mobile2/src/util/ustl-1.0/uutility.h b/media/libdrm/mobile2/src/util/ustl-1.0/uutility.h index 7b5ae64..2ee9a81 100644 --- a/media/libdrm/mobile2/src/util/ustl-1.0/uutility.h +++ b/media/libdrm/mobile2/src/util/ustl-1.0/uutility.h @@ -370,7 +370,7 @@ namespace simd { /// implicit casts to pointer from an integral type. Ironically, such an /// implicit cast is already detected by gcc. /// -#if defined(USTL_ANDROID_X86) +#if defined(USTL_ANDROID_X86) || defined(USTL_ANDROID_SH) #define OVERLOAD_POINTER_AND_SIZE_T_V2(name, arg1type) #else #define OVERLOAD_POINTER_AND_SIZE_T_V2(name, arg1type) \ diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 5352234..1787e1f 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -694,7 +694,9 @@ bool AudioSystem::isBluetoothScoDevice(audio_devices device) bool AudioSystem::isLowVisibility(stream_type stream) { - if (stream == AudioSystem::SYSTEM || stream == AudioSystem::NOTIFICATION) { + if (stream == AudioSystem::SYSTEM || + stream == AudioSystem::NOTIFICATION || + stream == AudioSystem::RING) { return true; } else { return false; diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index df673a4..49032e7 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -682,7 +682,7 @@ player_type getPlayerType(const char* url) int len = strlen(FILE_EXTS[i].extension); int start = lenURL - len; if (start > 0) { - if (!strncmp(url + start, FILE_EXTS[i].extension, len)) { + if (!strncasecmp(url + start, FILE_EXTS[i].extension, len)) { return FILE_EXTS[i].playertype; } } diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk index 9837845..518be8b 100644 --- a/opengl/libagl/Android.mk +++ b/opengl/libagl/Android.mk @@ -37,6 +37,10 @@ ifeq ($(TARGET_ARCH),arm) LOCAL_CFLAGS += -fstrict-aliasing endif +ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) + LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER +endif + ifneq ($(TARGET_SIMULATOR),true) # we need to access the private Bionic header <bionic_tls.h> LOCAL_C_INCLUDES += bionic/libc/private diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 13d078e..89a19b6 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -1467,7 +1467,7 @@ void glReadPixels( ogles_error(c, GL_INVALID_VALUE); return; } - if (x<0 || x<0) { + if (x<0 || y<0) { ogles_error(c, GL_INVALID_VALUE); return; } diff --git a/opengl/tests/gl_jni/jni/gl_code.cpp b/opengl/tests/gl_jni/jni/gl_code.cpp index 33b25ab..f031c79 100644 --- a/opengl/tests/gl_jni/jni/gl_code.cpp +++ b/opengl/tests/gl_jni/jni/gl_code.cpp @@ -180,4 +180,5 @@ JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobjec JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_changeBackground(JNIEnv * env, jobject obj) { background = 1.0f - background; -}
\ No newline at end of file +} + diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 9877342..ab186cf 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -305,9 +305,12 @@ public class SettingsProvider extends ContentProvider { } } else if (prefix == '-' && index >= 0) { // remove the provider from the list if present - // remove leading and trailing commas - if (index > 0) index--; - if (end < providers.length()) end++; + // remove leading or trailing comma + if (index > 0) { + index--; + } else if (end < providers.length()) { + end++; + } newProviders = providers.substring(0, index); if (end < providers.length()) { diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index 6bf7102..981cc93 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -855,7 +855,7 @@ class AppWidgetService extends IAppWidgetService.Stub out.startTag(null, "p"); out.attribute(null, "pkg", p.info.provider.getPackageName()); out.attribute(null, "cl", p.info.provider.getClassName()); - out.endTag(null, "h"); + out.endTag(null, "p"); p.tag = providerIndex; providerIndex++; } diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index e2e0ba9..afcba47 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -855,12 +855,26 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } + private void finishSession(SessionState sessionState) { + if (sessionState != null && sessionState.session != null) { + try { + sessionState.session.finishSession(); + } catch (RemoteException e) { + Log.w(TAG, "Session failed to close due to remote exception", e); + } + } + } + void clearCurMethodLocked() { if (mCurMethod != null) { for (ClientState cs : mClients.values()) { cs.sessionRequested = false; + finishSession(cs.curSession); cs.curSession = null; } + + finishSession(mEnabledSession); + mEnabledSession = null; mCurMethod = null; } mStatusBar.setIconVisibility(mInputMethodIcon, false); diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 024d8da..d679a5e 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -552,10 +552,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run } // Use system settings ContentResolver resolver = mContext.getContentResolver(); - String allowedProviders = Settings.Secure.getString(resolver, - Settings.Secure.LOCATION_PROVIDERS_ALLOWED); - return ((allowedProviders != null) && (allowedProviders.contains(provider))); + return Settings.Secure.isLocationProviderEnabled(resolver, provider); } private void checkPermissionsSafe(String provider) { @@ -1204,8 +1202,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run // Remove expired alerts if (intentsToRemove != null) { for (PendingIntent i : intentsToRemove) { - ProximityAlert alert = mProximityAlerts.remove(i); + ProximityAlert alert = mProximityAlerts.get(i); mProximitiesEntered.remove(alert); + removeProximityAlertLocked(i); } } } diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index 6df9f2b..cc78300 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -1861,7 +1861,7 @@ class PackageManagerService extends IPackageManager.Stub { && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 && (!mSafeMode || (p.applicationInfo.flags &ApplicationInfo.FLAG_SYSTEM) != 0)) { - finalList.add(p.applicationInfo); + finalList.add(PackageParser.generateApplicationInfo(p, flags)); } } } @@ -1977,12 +1977,6 @@ class PackageManagerService extends IPackageManager.Stub { } PackageParser.Package pkg = scanPackageLI(file, file, resFile, flags|PackageParser.PARSE_MUST_BE_APK, scanMode); - // Don't mess around with apps in system partition. - if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0) { - // Delete the apk - Log.w(TAG, "Cleaning up failed install of " + file); - file.delete(); - } } } @@ -2177,13 +2171,6 @@ class PackageManagerService extends IPackageManager.Stub { File scanFile, File destCodeFile, File destResourceFile, PackageParser.Package pkg, int parseFlags, int scanMode) { - if (scanFile == null || destCodeFile == null || - destResourceFile == null) { - // Bail out. The resource and code paths haven't been set. - Log.w(TAG, " Code and resource paths haven't been set correctly"); - mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK; - return null; - } mScanningPath = scanFile; if (pkg == null) { mLastScanError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME; diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 24caf1f..b90b03b 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -5478,7 +5478,7 @@ public class WindowManagerService extends IWindowManager.Stub + " fin=" + finished + " gfw=" + gotFirstWindow + " ed=" + eventDispatching + " tts=" + timeToSwitch + " wf=" + wasFrozen + " fp=" + focusPaused - + " mcf=" + mCurrentFocus + "}}"; + + " mcf=" + curFocus + "}}"; } }; private DispatchState mDispatchState = null; @@ -6435,18 +6435,30 @@ public class WindowManagerService extends IWindowManager.Stub case RawInputEvent.CLASS_KEYBOARD: KeyEvent ke = (KeyEvent)ev.event; if (ke.isDown()) { - lastKey = ke; - downTime = curTime; - keyRepeatCount = 0; lastKeyTime = curTime; - nextKeyTime = lastKeyTime - + ViewConfiguration.getLongPressTimeout(); - if (DEBUG_INPUT) Log.v( - TAG, "Received key down: first repeat @ " - + nextKeyTime); + if (lastKey != null && + ke.getKeyCode() == lastKey.getKeyCode()) { + keyRepeatCount++; + // Arbitrary long timeout to block + // repeating here since we know that + // the device driver takes care of it. + nextKeyTime = lastKeyTime + LONG_WAIT; + if (DEBUG_INPUT) Log.v( + TAG, "Received repeated key down"); + } else { + downTime = curTime; + keyRepeatCount = 0; + nextKeyTime = lastKeyTime + + ViewConfiguration.getLongPressTimeout(); + if (DEBUG_INPUT) Log.v( + TAG, "Received key down: first repeat @ " + + nextKeyTime); + } + lastKey = ke; } else { lastKey = null; downTime = 0; + keyRepeatCount = 0; // Arbitrary long timeout. lastKeyTime = curTime; nextKeyTime = curTime + LONG_WAIT; @@ -6454,7 +6466,12 @@ public class WindowManagerService extends IWindowManager.Stub TAG, "Received key up: ignore repeat @ " + nextKeyTime); } - dispatchKey((KeyEvent)ev.event, 0, 0); + if (keyRepeatCount > 0) { + dispatchKey(KeyEvent.changeTimeRepeat(ke, + ke.getEventTime(), keyRepeatCount), 0, 0); + } else { + dispatchKey(ke, 0, 0); + } mQueue.recycleEvent(ev); break; case RawInputEvent.CLASS_TOUCHSCREEN: @@ -8520,7 +8537,8 @@ public class WindowManagerService extends IWindowManager.Stub final int N = allAppWindows.size(); for (int i=0; i<N; i++) { WindowState win = allAppWindows.get(i); - if (win == startingWindow || win.mAppFreezing) { + if (win == startingWindow || win.mAppFreezing + || win.mAttrs.type == TYPE_APPLICATION_STARTING) { continue; } if (DEBUG_VISIBILITY) { @@ -10985,6 +11003,7 @@ public class WindowManagerService extends IWindowManager.Stub try { mDimSurface = new Surface(session, 0, -1, 16, 16, PixelFormat.OPAQUE, Surface.FX_SURFACE_DIM); + mDimSurface.setAlpha(0.0f); } catch (Exception e) { Log.e(TAG, "Exception creating Dim surface", e); } diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 5f6356d..9e9552a 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -3566,7 +3566,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r + " in new task " + r.task); newTask = true; - addRecentTask(r.task); + addRecentTaskLocked(r.task); } else if (sourceRecord != null) { if (!addingToTask && @@ -3855,7 +3855,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } - private final void addRecentTask(TaskRecord task) { + private final void addRecentTaskLocked(TaskRecord task) { // Remove any existing entries that are the same kind of task. int N = mRecentTasks.size(); for (int i=0; i<N; i++) { @@ -4931,9 +4931,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, Uri.fromParts("package", packageName, null)); intent.putExtra(Intent.EXTRA_UID, pkgUid); - broadcastIntentLocked(null, null, intent, - null, null, 0, null, null, null, - false, false, MY_PID, Process.SYSTEM_UID); + synchronized (this) { + broadcastIntentLocked(null, null, intent, + null, null, 0, null, null, null, + false, false, MY_PID, Process.SYSTEM_UID); + } } catch (RemoteException e) { } } finally { @@ -5668,7 +5670,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mProcessesOnHold); for (int ip=0; ip<NP; ip++) { - this.startProcessLocked(procs.get(ip), "on-hold", null); + synchronized (this) { + this.startProcessLocked(procs.get(ip), "on-hold", null); + } } } if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { @@ -6887,7 +6891,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen taskTopI = -1; } replyChainEnd = -1; - addRecentTask(target.task); + addRecentTaskLocked(target.task); } else if (forceReset || finishOnTaskLaunch || clearWhenTaskReset) { // If the activity should just be removed -- either @@ -7109,7 +7113,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen moved.add(0, r); top--; if (first) { - addRecentTask(r.task); + addRecentTaskLocked(r.task); first = false; } } @@ -7134,11 +7138,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen mWindowManager.validateAppTokens(mHistory); } - finishTaskMove(task); + finishTaskMoveLocked(task); EventLog.writeEvent(LOG_TASK_TO_FRONT, task); } - private final void finishTaskMove(int task) { + private final void finishTaskMoveLocked(int task) { resumeTopActivityLocked(null); } @@ -7256,7 +7260,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen mWindowManager.validateAppTokens(mHistory); } - finishTaskMove(task); + finishTaskMoveLocked(task); return true; } @@ -7879,9 +7883,14 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } public static final void installSystemProviders() { - ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); - List providers = mSelf.generateApplicationProvidersLocked(app); - mSystemThread.installSystemProviders(providers); + List providers = null; + synchronized (mSelf) { + ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); + providers = mSelf.generateApplicationProvidersLocked(app); + } + if (providers != null) { + mSystemThread.installSystemProviders(providers); + } } // ========================================================= @@ -8156,11 +8165,15 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } public void registerActivityWatcher(IActivityWatcher watcher) { - mWatchers.register(watcher); + synchronized (this) { + mWatchers.register(watcher); + } } public void unregisterActivityWatcher(IActivityWatcher watcher) { - mWatchers.unregister(watcher); + synchronized (this) { + mWatchers.unregister(watcher); + } } public final void enterSafeMode() { @@ -11564,7 +11577,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // BROADCASTS // ========================================================= - private final List getStickies(String action, IntentFilter filter, + private final List getStickiesLocked(String action, IntentFilter filter, List cur) { final ContentResolver resolver = mContext.getContentResolver(); final ArrayList<Intent> list = mStickyBroadcasts.get(action); @@ -11616,10 +11629,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (actions != null) { while (actions.hasNext()) { String action = (String)actions.next(); - allSticky = getStickies(action, filter, allSticky); + allSticky = getStickiesLocked(action, filter, allSticky); } } else { - allSticky = getStickies(null, filter, allSticky); + allSticky = getStickiesLocked(null, filter, allSticky); } // The first sticky in the list is returned directly back to @@ -13357,7 +13370,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen /** * Returns true if things are idle enough to perform GCs. */ - private final boolean canGcNow() { + private final boolean canGcNowLocked() { return mParallelBroadcasts.size() == 0 && mOrderedBroadcasts.size() == 0 && (mSleeping || (mResumedActivity != null && @@ -13373,7 +13386,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (N <= 0) { return; } - if (canGcNow()) { + if (canGcNowLocked()) { while (mProcessesToGc.size() > 0) { ProcessRecord proc = mProcessesToGc.remove(0); if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) { @@ -13401,7 +13414,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen * If all looks good, perform GCs on all processes waiting for them. */ final void performAppGcsIfAppropriateLocked() { - if (canGcNow()) { + if (canGcNowLocked()) { performAppGcsLocked(); return; } diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java index 89761a8..2f2cc32 100644 --- a/services/java/com/android/server/am/ServiceRecord.java +++ b/services/java/com/android/server/am/ServiceRecord.java @@ -29,6 +29,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; +import android.util.Log; import java.io.PrintWriter; import java.util.ArrayList; @@ -267,6 +268,9 @@ class ServiceRecord extends Binder { int[] outId = new int[1]; inm.enqueueNotification(localPackageName, localForegroundId, localForegroundNoti, outId); + } catch (RuntimeException e) { + Log.w(ActivityManagerService.TAG, "Error showing notification for service", + e); } catch (RemoteException e) { } } @@ -288,6 +292,9 @@ class ServiceRecord extends Binder { } try { inm.cancelNotification(localPackageName, localForegroundId); + } catch (RuntimeException e) { + Log.w(ActivityManagerService.TAG, "Error canceling notification for" + + " service", e); } catch (RemoteException e) { } } diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java index bee0930..9a3baff 100644 --- a/services/java/com/android/server/status/StatusBarPolicy.java +++ b/services/java/com/android/server/status/StatusBarPolicy.java @@ -843,7 +843,9 @@ public class StatusBarPolicy { && ((mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_0) || (mServiceState.getRadioTechnology() - == ServiceState.RADIO_TECHNOLOGY_EVDO_A))); + == ServiceState.RADIO_TECHNOLOGY_EVDO_A) + || (mServiceState.getRadioTechnology() + == ServiceState.RADIO_TECHNOLOGY_EVDO_B))); } private boolean hasService() { @@ -958,7 +960,6 @@ public class StatusBarPolicy { } private final void updateDataNetType(int net) { - switch (net) { case TelephonyManager.NETWORK_TYPE_EDGE: mDataIconList = sDataNetType_e; @@ -984,6 +985,7 @@ public class StatusBarPolicy { break; case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through case TelephonyManager.NETWORK_TYPE_EVDO_A: + case TelephonyManager.NETWORK_TYPE_EVDO_B: mDataIconList = sDataNetType_3g; break; default: diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java index ad7dfc9..2f7666d 100644 --- a/telephony/java/android/telephony/NeighboringCellInfo.java +++ b/telephony/java/android/telephony/NeighboringCellInfo.java @@ -133,8 +133,11 @@ public class NeighboringCellInfo implements Parcelable case NETWORK_TYPE_GPRS: case NETWORK_TYPE_EDGE: mNetworkType = radioType; - mLac = Integer.valueOf(location.substring(0, 4), 16); - mCid = Integer.valueOf(location.substring(4), 16); + // check if 0xFFFFFFFF for UNKNOWN_CID + if (!location.equalsIgnoreCase("FFFFFFFF")) { + mCid = Integer.valueOf(location.substring(4), 16); + mLac = Integer.valueOf(location.substring(0, 4), 16); + } break; case NETWORK_TYPE_UMTS: case NETWORK_TYPE_HSDPA: @@ -293,4 +296,4 @@ public class NeighboringCellInfo implements Parcelable return new NeighboringCellInfo[size]; } }; -}
\ No newline at end of file +} diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index 1aa1c76..3f08676 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -689,7 +689,8 @@ public class PhoneNumberUtils return ""; } - if ((bytes[offset] & 0xff) == TOA_International) { + //Only TON field should be taken in concideration + if ((bytes[offset] & 0xf0) == (TOA_International & 0xf0)) { prependPlus = true; } diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 48a40fa..446bbc2 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -89,6 +89,8 @@ public class ServiceState implements Parcelable { public static final int RADIO_TECHNOLOGY_HSUPA = 10; /** @hide */ public static final int RADIO_TECHNOLOGY_HSPA = 11; + /** @hide */ + public static final int RADIO_TECHNOLOGY_EVDO_B = 12; /** * Available registration states for GSM, UMTS and CDMA. @@ -365,7 +367,6 @@ public class ServiceState implements Parcelable { @Override public String toString() { String radioTechnology = new String("Error in radioTechnology"); - switch(this.mRadioTechnology) { case 0: radioTechnology = "Unknown"; @@ -403,6 +404,9 @@ public class ServiceState implements Parcelable { case 11: radioTechnology = "HSPA"; break; + case 12: + radioTechnology = "EvDo rev. B"; + break; default: Log.w(LOG_TAG, "mRadioTechnology variable out of range."); break; diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 3122722..f5e9751 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -398,4 +398,6 @@ public final class SmsManager { static public final int RESULT_ERROR_NO_SERVICE = 4; /** Failed because we reached the sending queue limit. {@hide} */ static public final int RESULT_ERROR_LIMIT_EXCEEDED = 5; + /** Failed because FDN is enabled. {@hide} */ + static public final int RESULT_ERROR_FDN_CHECK_FAILURE = 6; } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 6685c18..310fc7f 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -386,6 +386,9 @@ public class TelephonyManager { public static final int NETWORK_TYPE_HSUPA = 9; /** Current network is HSPA */ public static final int NETWORK_TYPE_HSPA = 10; + /** Current network is EVDO revision B*/ + public static final int NETWORK_TYPE_EVDO_B = 12; + /** * Returns a constant indicating the radio technology (network type) @@ -402,6 +405,7 @@ public class TelephonyManager { * @see #NETWORK_TYPE_CDMA * @see #NETWORK_TYPE_EVDO_0 * @see #NETWORK_TYPE_EVDO_A + * @see #NETWORK_TYPE_EVDO_B * @see #NETWORK_TYPE_1xRTT */ public int getNetworkType() { @@ -449,6 +453,8 @@ public class TelephonyManager { return "CDMA - EvDo rev. 0"; case NETWORK_TYPE_EVDO_A: return "CDMA - EvDo rev. A"; + case NETWORK_TYPE_EVDO_B: + return "CDMA - EvDo rev. B"; case NETWORK_TYPE_1xRTT: return "CDMA - 1xRTT"; default: diff --git a/telephony/java/com/android/internal/telephony/CommandException.java b/telephony/java/com/android/internal/telephony/CommandException.java index a5d11cf..d7adab3 100644 --- a/telephony/java/com/android/internal/telephony/CommandException.java +++ b/telephony/java/com/android/internal/telephony/CommandException.java @@ -37,6 +37,10 @@ public class CommandException extends RuntimeException { OP_NOT_ALLOWED_DURING_VOICE_CALL, OP_NOT_ALLOWED_BEFORE_REG_NW, SMS_FAIL_RETRY, + SIM_ABSENT, + SUBSCRIPTION_NOT_AVAILABLE, + MODE_NOT_SUPPORTED, + FDN_CHECK_FAILURE, } public CommandException(Error e) { @@ -68,6 +72,14 @@ public class CommandException extends RuntimeException { return new CommandException(Error.OP_NOT_ALLOWED_BEFORE_REG_NW); case RILConstants.SMS_SEND_FAIL_RETRY: return new CommandException(Error.SMS_FAIL_RETRY); + case RILConstants.SIM_ABSENT: + return new CommandException(Error.SIM_ABSENT); + case RILConstants.SUBSCRIPTION_NOT_AVAILABLE: + return new CommandException(Error.SUBSCRIPTION_NOT_AVAILABLE); + case RILConstants.MODE_NOT_SUPPORTED: + return new CommandException(Error.MODE_NOT_SUPPORTED); + case RILConstants.FDN_CHECK_FAILURE: + return new CommandException(Error.FDN_CHECK_FAILURE); default: Log.e("GSM", "Unrecognized RIL errno " + ril_errno); return new CommandException(Error.INVALID_RESPONSE); diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java index d90c305..8e03c5a 100644 --- a/telephony/java/com/android/internal/telephony/CommandsInterface.java +++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java @@ -664,6 +664,19 @@ public interface CommandsInterface { * retMsg.obj = AsyncResult ar * ar.exception carries exception on failure * ar.userObject contains the orignal value of result.obj + * ar.result is null on success and failure + * + * CLIR_DEFAULT == on "use subscription default value" + * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation) + * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation) + */ + void dial(String address, int clirMode, UUSInfo uusInfo, Message result); + + /** + * returned message + * retMsg.obj = AsyncResult ar + * ar.exception carries exception on failure + * ar.userObject contains the orignal value of result.obj * ar.result is String containing IMSI on success */ void getIMSI(Message result); diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java index 37e8a99..0bcb63a 100644 --- a/telephony/java/com/android/internal/telephony/Connection.java +++ b/telephony/java/com/android/internal/telephony/Connection.java @@ -50,6 +50,7 @@ public abstract class Connection { CS_RESTRICTED, /* call was blocked by restricted all voice access */ CS_RESTRICTED_NORMAL, /* call was blocked by restricted normal voice access */ CS_RESTRICTED_EMERGENCY, /* call was blocked by restricted emergency voice access */ + UNOBTAINABLE_NUMBER, /* Unassigned number (3GPP TS 24.008 table 10.5.123) */ CDMA_LOCKED_UNTIL_POWER_CYCLE, /* MS is locked until next power cycle */ CDMA_DROP, CDMA_INTERCEPT, /* INTERCEPT order received, MS state idle entered */ @@ -273,6 +274,13 @@ public abstract class Connection { public abstract int getNumberPresentation(); /** + * Returns the User to User Signaling (UUS) information associated with + * incoming and waiting calls + * @return UUSInfo containing the UUS userdata. + */ + public abstract UUSInfo getUUSInfo(); + + /** * Build a human representation of a connection instance, suitable for debugging. * Don't log personal stuff unless in debug mode. * @return a string representing the internal state of this connection. diff --git a/telephony/java/com/android/internal/telephony/DriverCall.java b/telephony/java/com/android/internal/telephony/DriverCall.java index 0d9a60f..2382441 100644 --- a/telephony/java/com/android/internal/telephony/DriverCall.java +++ b/telephony/java/com/android/internal/telephony/DriverCall.java @@ -49,6 +49,7 @@ public class DriverCall implements Comparable { public int numberPresentation; public String name; public int namePresentation; + public UUSInfo uusInfo; /** returns null on error */ static DriverCall diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java index 11386ae..24f08cb 100644 --- a/telephony/java/com/android/internal/telephony/Phone.java +++ b/telephony/java/com/android/internal/telephony/Phone.java @@ -789,6 +789,19 @@ public interface Phone { Connection dial(String dialString) throws CallStateException; /** + * Initiate a new voice connection with supplementary User to User + * Information. This happens asynchronously, so you cannot assume the audio + * path is connected (or a call index has been assigned) until + * PhoneStateChanged notification has occurred. + * + * @exception CallStateException if a new outgoing call is not currently + * possible because no more call slots exist or a call exists + * that is dialing, alerting, ringing, or waiting. Other + * errors are handled asynchronously. + */ + Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException; + + /** * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated * without SEND (so <code>dial</code> is not appropriate). * diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java index eb406b7..a2554ba 100644 --- a/telephony/java/com/android/internal/telephony/PhoneBase.java +++ b/telephony/java/com/android/internal/telephony/PhoneBase.java @@ -540,7 +540,7 @@ public abstract class PhoneBase extends Handler implements Phone { private void setPropertiesByCarrier() { String carrier = SystemProperties.get("ro.carrier"); - if (null == carrier || 0 == carrier.length()) { + if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) { return; } diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java index cd72752..803b736 100644 --- a/telephony/java/com/android/internal/telephony/PhoneFactory.java +++ b/telephony/java/com/android/internal/telephony/PhoneFactory.java @@ -109,13 +109,13 @@ public class PhoneFactory { int phoneType = getPhoneType(networkMode); if (phoneType == Phone.PHONE_TYPE_GSM) { + Log.i(LOG_TAG, "Creating GSMPhone"); sProxyPhone = new PhoneProxy(new GSMPhone(context, sCommandsInterface, sPhoneNotifier)); - Log.i(LOG_TAG, "Creating GSMPhone"); } else if (phoneType == Phone.PHONE_TYPE_CDMA) { + Log.i(LOG_TAG, "Creating CDMAPhone"); sProxyPhone = new PhoneProxy(new CDMAPhone(context, sCommandsInterface, sPhoneNotifier)); - Log.i(LOG_TAG, "Creating CDMAPhone"); } sMadeDefaults = true; diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java index 1ef8d37..77c7c28 100644 --- a/telephony/java/com/android/internal/telephony/PhoneProxy.java +++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java @@ -415,6 +415,10 @@ public class PhoneProxy extends Handler implements Phone { return mActivePhone.dial(dialString); } + public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException { + return mActivePhone.dial(dialString, uusInfo); + } + public boolean handlePinMmi(String dialString) { return mActivePhone.handlePinMmi(dialString); } diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java index 86cb6fb..7239889 100644 --- a/telephony/java/com/android/internal/telephony/RIL.java +++ b/telephony/java/com/android/internal/telephony/RIL.java @@ -788,11 +788,25 @@ public final class RIL extends BaseCommands implements CommandsInterface { public void dial (String address, int clirMode, Message result) { + dial(address, clirMode, null, result); + } + + public void + dial(String address, int clirMode, UUSInfo uusInfo, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result); rr.mp.writeString(address); rr.mp.writeInt(clirMode); + if (uusInfo == null) { + rr.mp.writeInt(0); // UUS information is absent + } else { + rr.mp.writeInt(1); // UUS information is present + rr.mp.writeInt(uusInfo.getType()); + rr.mp.writeInt(uusInfo.getDcs()); + rr.mp.writeByteArray(uusInfo.getUserData()); + } + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); @@ -2825,6 +2839,24 @@ public final class RIL extends BaseCommands implements CommandsInterface { dc.numberPresentation = DriverCall.presentationFromCLIP(np); dc.name = p.readString(); dc.namePresentation = p.readInt(); + int uusInfoPresent = p.readInt(); + if (uusInfoPresent == 1) { + dc.uusInfo = new UUSInfo(); + dc.uusInfo.setType(p.readInt()); + dc.uusInfo.setDcs(p.readInt()); + byte[] userData = p.createByteArray(); + dc.uusInfo.setUserData(userData); + Log + .v(LOG_TAG, String.format("Incoming UUS : type=%d, dcs=%d, length=%d", + dc.uusInfo.getType(), dc.uusInfo.getDcs(), + dc.uusInfo.getUserData().length)); + Log.v(LOG_TAG, "Incoming UUS : data (string)=" + + new String(dc.uusInfo.getUserData())); + Log.v(LOG_TAG, "Incoming UUS : data (hex): " + + IccUtils.bytesToHexString(dc.uusInfo.getUserData())); + } else { + Log.v(LOG_TAG, "Incoming UUS : NOT present!"); + } // Make sure there's a leading + on addresses with a TOA of 145 dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA); diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 4d8c7ec..be1fbf1 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -45,6 +45,11 @@ public interface RILConstants { int OP_NOT_ALLOWED_BEFORE_REG_NW = 9; /* request is not allowed before device registers to network */ int SMS_SEND_FAIL_RETRY = 10; /* send sms fail and need retry */ + int SIM_ABSENT = 11; /* ICC card is absent */ + int SUBSCRIPTION_NOT_AVAILABLE = 12; /* fail to find CDMA subscription from specified + location */ + int MODE_NOT_SUPPORTED = 13; /* HW does not support preferred network type */ + int FDN_CHECK_FAILURE = 14; /* send operation barred error when FDN is enabled */ /* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */ int NETWORK_MODE_WCDMA_PREF = 0; /* GSM/WCDMA (WCDMA preferred) */ diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java index 53c0bef..98d4b1d 100644 --- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java @@ -62,6 +62,7 @@ import static android.telephony.SmsManager.RESULT_ERROR_NO_SERVICE; import static android.telephony.SmsManager.RESULT_ERROR_NULL_PDU; import static android.telephony.SmsManager.RESULT_ERROR_RADIO_OFF; import static android.telephony.SmsManager.RESULT_ERROR_LIMIT_EXCEEDED; +import static android.telephony.SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE; public abstract class SMSDispatcher extends Handler { @@ -109,6 +110,12 @@ public abstract class SMSDispatcher extends Handler { /** Stop the sending */ static final protected int EVENT_STOP_SENDING = 10; + /** Memory status reporting is acknowledged by RIL */ + static final protected int EVENT_REPORT_MEMORY_STATUS_DONE = 11; + + /** Radio is ON */ + static final protected int EVENT_RADIO_ON = 12; + protected Phone mPhone; protected Context mContext; protected ContentResolver mResolver; @@ -152,6 +159,7 @@ public abstract class SMSDispatcher extends Handler { private SmsMessageBase.SubmitPduBase mSubmitPduBase; protected boolean mStorageAvailable = true; + protected boolean mReportMemoryStatusPending = false; protected static int getNextConcatenatedRef() { sConcatenatedRef += 1; @@ -235,6 +243,7 @@ public abstract class SMSDispatcher extends Handler { mCm.setOnNewSMS(this, EVENT_NEW_SMS, null); mCm.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null); mCm.setOnIccSmsFull(this, EVENT_ICC_FULL, null); + mCm.registerForOn(this, EVENT_RADIO_ON, null); // Don't always start message ref at 0. sConcatenatedRef = new Random().nextInt(256); @@ -253,6 +262,7 @@ public abstract class SMSDispatcher extends Handler { mCm.unSetOnNewSMS(this); mCm.unSetOnSmsStatus(this); mCm.unSetOnIccSmsFull(this); + mCm.unregisterForOn(this); } protected void finalize() { @@ -370,6 +380,26 @@ public abstract class SMSDispatcher extends Handler { removeMessages(EVENT_ALERT_TIMEOUT, msg.obj); } break; + + case EVENT_REPORT_MEMORY_STATUS_DONE: + ar = (AsyncResult)msg.obj; + if (ar.exception != null) { + mReportMemoryStatusPending = true; + Log.v(TAG, "Memory status report to modem pending : mStorageAvailable = " + + mStorageAvailable); + } else { + mReportMemoryStatusPending = false; + } + break; + + case EVENT_RADIO_ON: + if (mReportMemoryStatusPending) { + Log.v(TAG, "Sending pending memory status report : mStorageAvailable = " + + mStorageAvailable); + mCm.reportSmsMemoryStatus(mStorageAvailable, + obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE)); + } + break; } } @@ -470,13 +500,20 @@ public abstract class SMSDispatcher extends Handler { Message retryMsg = obtainMessage(EVENT_SEND_RETRY, tracker); sendMessageDelayed(retryMsg, SEND_RETRY_DELAY); } else if (tracker.mSentIntent != null) { + int error = RESULT_ERROR_GENERIC_FAILURE; + + if (((CommandException)(ar.exception)).getCommandError() + == CommandException.Error.FDN_CHECK_FAILURE) { + error = RESULT_ERROR_FDN_CHECK_FAILURE; + } // Done retrying; return an error to the app. try { Intent fillIn = new Intent(); if (ar.result != null) { fillIn.putExtra("errorCode", ((SmsResponse)ar.result).errorCode); } - tracker.mSentIntent.send(mContext, RESULT_ERROR_GENERIC_FAILURE, fillIn); + tracker.mSentIntent.send(mContext, error, fillIn); + } catch (CanceledException ex) {} } } @@ -940,10 +977,10 @@ public abstract class SMSDispatcher extends Handler { public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_LOW)) { mStorageAvailable = false; - mCm.reportSmsMemoryStatus(false, null); + mCm.reportSmsMemoryStatus(false, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE)); } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_OK)) { mStorageAvailable = true; - mCm.reportSmsMemoryStatus(true, null); + mCm.reportSmsMemoryStatus(true, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE)); } else { // Assume the intent is one of the SMS receive intents that // was sent as an ordered broadcast. Check result and ACK. diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java index 6892998..be4fdb4 100644 --- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java @@ -44,6 +44,7 @@ public abstract class ServiceStateTracker extends Handler { protected static final int DATA_ACCESS_HSDPA = 9; protected static final int DATA_ACCESS_HSUPA = 10; protected static final int DATA_ACCESS_HSPA = 11; + protected static final int DATA_ACCESS_CDMA_EvDo_B = 12; protected CommandsInterface cm; diff --git a/telephony/java/com/android/internal/telephony/UUSInfo.java b/telephony/java/com/android/internal/telephony/UUSInfo.java new file mode 100644 index 0000000..801b845 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/UUSInfo.java @@ -0,0 +1,100 @@ +/* + * 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.internal.telephony; + +public class UUSInfo { + + /* + * User-to-User signaling Info activation types derived from 3GPP 23.087 + * v8.0 + */ + + public static final int UUS_TYPE1_IMPLICIT = 0; + + public static final int UUS_TYPE1_REQUIRED = 1; + + public static final int UUS_TYPE1_NOT_REQUIRED = 2; + + public static final int UUS_TYPE2_REQUIRED = 3; + + public static final int UUS_TYPE2_NOT_REQUIRED = 4; + + public static final int UUS_TYPE3_REQUIRED = 5; + + public static final int UUS_TYPE3_NOT_REQUIRED = 6; + + /* + * User-to-User Signaling Information data coding schemes. Possible values + * for Octet 3 (Protocol Discriminator field) in the UUIE. The values have + * been specified in section 10.5.4.25 of 3GPP TS 24.008 + */ + + public static final int UUS_DCS_USP = 0; /* User specified protocol */ + + public static final int UUS_DCS_OSIHLP = 1; /* OSI higher layer protocol */ + + public static final int UUS_DCS_X244 = 2; /* X.244 */ + + public static final int UUS_DCS_RMCF = 3; /* + * Reserved for system management + * convergence function + */ + + public static final int UUS_DCS_IA5c = 4; /* IA5 characters */ + + private int uusType; + + private int uusDcs; + + private byte[] uusData; + + public UUSInfo() { + this.uusType = UUS_TYPE1_IMPLICIT; + this.uusDcs = UUS_DCS_IA5c; + this.uusData = null; + } + + public UUSInfo(int uusType, int uusDcs, byte[] uusData) { + this.uusType = uusType; + this.uusDcs = uusDcs; + this.uusData = uusData; + } + + public int getDcs() { + return uusDcs; + } + + public void setDcs(int uusDcs) { + this.uusDcs = uusDcs; + } + + public int getType() { + return uusType; + } + + public void setType(int uusType) { + this.uusType = uusType; + } + + public byte[] getUserData() { + return uusData; + } + + public void setUserData(byte[] uusData) { + this.uusData = uusData; + } +} diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java index 3548cad..ea80ea4 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java @@ -62,11 +62,13 @@ import com.android.internal.telephony.PhoneProxy; import com.android.internal.telephony.PhoneSubInfo; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyProperties; +import com.android.internal.telephony.UUSInfo; import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA; import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC; import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY; +import java.util.ArrayList; import java.util.List; @@ -101,6 +103,7 @@ public class CDMAPhone extends PhoneBase { RuimFileHandler mRuimFileHandler; RuimRecords mRuimRecords; RuimCard mRuimCard; + ArrayList <CdmaMmiCode> mPendingMmis = new ArrayList<CdmaMmiCode>(); RuimPhoneBookInterfaceManager mRuimPhoneBookInterfaceManager; RuimSmsInterfaceManager mRuimSmsInterfaceManager; PhoneSubInfo mSubInfo; @@ -223,6 +226,8 @@ public class CDMAPhone extends PhoneBase { mSST.unregisterForNetworkAttach(this); //EVENT_REGISTERED_TO_NETWORK mCM.unSetOnSuppServiceNotification(this); + mPendingMmis.clear(); + //Force all referenced classes to unregister their former registered events mCT.dispose(); mDataConnection.dispose(); @@ -354,6 +359,10 @@ public class CDMAPhone extends PhoneBase { return mCT.dial(newDialString); } + public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException { + throw new CallStateException("Sending UUS information NOT supported in CDMA!"); + } + public SignalStrength getSignalStrength() { return mSST.mSignalStrength; } @@ -365,8 +374,7 @@ public class CDMAPhone extends PhoneBase { public List<? extends MmiCode> getPendingMmiCodes() { - Log.e(LOG_TAG, "method getPendingMmiCodes is NOT supported in CDMA!"); - return null; + return mPendingMmis; } public void registerForSuppServiceNotification( @@ -383,6 +391,15 @@ public class CDMAPhone extends PhoneBase { return false; } + boolean isInCall() { + CdmaCall.State foregroundCallState = getForegroundCall().getState(); + CdmaCall.State backgroundCallState = getBackgroundCall().getState(); + CdmaCall.State ringingCallState = getRingingCall().getState(); + + return (foregroundCallState.isAlive() || backgroundCallState.isAlive() || ringingCallState + .isAlive()); + } + public void setNetworkSelectionModeAutomatic(Message response) { Log.e(LOG_TAG, "method setNetworkSelectionModeAutomatic is NOT supported in CDMA!"); @@ -482,7 +499,18 @@ public class CDMAPhone extends PhoneBase { } public boolean handlePinMmi(String dialString) { - Log.e(LOG_TAG, "method handlePinMmi is NOT supported in CDMA!"); + CdmaMmiCode mmi = CdmaMmiCode.newFromDialString(dialString, this); + + if (mmi == null) { + Log.e(LOG_TAG, "Mmi is NULL!"); + return false; + } else if (mmi.isPukCommand()) { + mPendingMmis.add(mmi); + mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); + mmi.processCode(); + return true; + } + Log.e(LOG_TAG, "Unrecognized mmi!"); return false; } @@ -494,6 +522,22 @@ public class CDMAPhone extends PhoneBase { (mDataConnection.getDataOnRoamingEnabled() || !getServiceState().getRoaming()); } + /** + * Removes the given MMI from the pending list and notifies registrants that + * it is complete. + * + * @param mmi MMI that is done + */ + void onMMIDone(CdmaMmiCode mmi) { + /* + * Only notify complete if it's on the pending list. Otherwise, it's + * already been handled (eg, previously canceled). + */ + if (mPendingMmis.remove(mmi)) { + mMmiCompleteRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); + } + } + public void setLine1Number(String alphaTag, String number, Message onComplete) { Log.e(LOG_TAG, "setLine1Number: not possible in CDMA"); } @@ -1436,5 +1480,4 @@ public class CDMAPhone extends PhoneBase { } return false; } - } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java index f637d33..81dec21 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java @@ -933,4 +933,10 @@ public class CdmaConnection extends Connection { public int getNumberPresentation() { return numberPresentation; } + + @Override + public UUSInfo getUUSInfo() { + // UUS information not supported in CDMA + return null; + } } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java b/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java new file mode 100644 index 0000000..8dd8c2e --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony.cdma; + +import android.content.Context; + +import com.android.internal.telephony.CommandException; +import com.android.internal.telephony.MmiCode; + +import android.os.AsyncResult; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +/** + * This class can handle Puk code Mmi + * + * {@hide} + * + */ +public final class CdmaMmiCode extends Handler implements MmiCode { + static final String LOG_TAG = "CDMA_MMI"; + + // Constants + + // From TS 22.030 6.5.2 + static final String ACTION_REGISTER = "**"; + + // Supp Service codes from TS 22.030 Annex B + static final String SC_PUK = "05"; + + // Event Constant + + static final int EVENT_SET_COMPLETE = 1; + + // Instance Variables + + CDMAPhone phone; + Context context; + + String action; // ACTION_REGISTER + String sc; // Service Code + String sia, sib, sic; // Service Info a,b,c + String poundString; // Entire MMI string up to and including # + String dialingNumber; + String pwd; // For password registration + + State state = State.PENDING; + CharSequence message; + + // Class Variables + + static Pattern sPatternSuppService = Pattern.compile( + "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)"); +/* 1 2 3 4 5 6 7 8 9 10 11 12 + + 1 = Full string up to and including # + 2 = action + 3 = service code + 5 = SIA + 7 = SIB + 9 = SIC + 10 = dialing number +*/ + + static final int MATCH_GROUP_POUND_STRING = 1; + static final int MATCH_GROUP_ACTION = 2; + static final int MATCH_GROUP_SERVICE_CODE = 3; + static final int MATCH_GROUP_SIA = 5; + static final int MATCH_GROUP_SIB = 7; + static final int MATCH_GROUP_SIC = 9; + static final int MATCH_GROUP_PWD_CONFIRM = 11; + static final int MATCH_GROUP_DIALING_NUMBER = 12; + + + // Public Class methods + + /** + * Check if provided string contains Mmi code in it and create corresponding + * Mmi if it does + */ + + public static CdmaMmiCode + newFromDialString(String dialString, CDMAPhone phone) { + Matcher m; + CdmaMmiCode ret = null; + + m = sPatternSuppService.matcher(dialString); + + // Is this formatted like a standard supplementary service code? + if (m.matches()) { + ret = new CdmaMmiCode(phone); + ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING)); + ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION)); + ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE)); + ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA)); + ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB)); + ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC)); + ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM)); + ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER)); + + } + + return ret; + } + + // Private Class methods + + /** make empty strings be null. + * Regexp returns empty strings for empty groups + */ + private static String + makeEmptyNull (String s) { + if (s != null && s.length() == 0) return null; + + return s; + } + + // Constructor + + CdmaMmiCode (CDMAPhone phone) { + super(phone.getHandler().getLooper()); + this.phone = phone; + this.context = phone.getContext(); + } + + // MmiCode implementation + + public State + getState() { + return state; + } + + public CharSequence + getMessage() { + return message; + } + + // inherited javadoc suffices + public void + cancel() { + // Complete or failed cannot be cancelled + if (state == State.COMPLETE || state == State.FAILED) { + return; + } + + state = State.CANCELLED; + phone.onMMIDone (this); + } + + public boolean isCancelable() { + return false; + } + + // Instance Methods + + /** + * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related + */ + boolean isPukCommand() { + return sc != null && sc.equals(SC_PUK); + } + + boolean isRegister() { + return action != null && action.equals(ACTION_REGISTER); + } + + public boolean isUssdRequest() { + Log.w(LOG_TAG, "isUssdRequest is not implemented in CdmaMmiCode"); + return false; + } + + /** Process a MMI PUK code */ + void + processCode () { + try { + if (isPukCommand()) { + // sia = old PUK + // sib = new PIN + // sic = new PIN + String oldPinOrPuk = sia; + String newPin = sib; + int pinLen = newPin.length(); + if (isRegister()) { + if (!newPin.equals(sic)) { + // password mismatch; return error + handlePasswordError(com.android.internal.R.string.mismatchPin); + } else if (pinLen < 4 || pinLen > 8 ) { + // invalid length + handlePasswordError(com.android.internal.R.string.invalidPin); + } else { + phone.mCM.supplyIccPuk(oldPinOrPuk, newPin, + obtainMessage(EVENT_SET_COMPLETE, this)); + } + } else { + throw new RuntimeException ("Invalid or Unsupported MMI Code"); + } + } else { + throw new RuntimeException ("Invalid or Unsupported MMI Code"); + } + } catch (RuntimeException exc) { + state = State.FAILED; + message = context.getText(com.android.internal.R.string.mmiError); + phone.onMMIDone(this); + } + } + + private void handlePasswordError(int res) { + state = State.FAILED; + StringBuilder sb = new StringBuilder(getScString()); + sb.append("\n"); + sb.append(context.getText(res)); + message = sb; + phone.onMMIDone(this); + } + + public void + handleMessage (Message msg) { + AsyncResult ar; + + if (msg.what == EVENT_SET_COMPLETE) { + ar = (AsyncResult) (msg.obj); + onSetComplete(ar); + } else { + Log.e(LOG_TAG, "Unexpected reply"); + } + } + // Private instance methods + + private CharSequence getScString() { + if (sc != null) { + if (isPukCommand()) { + return context.getText(com.android.internal.R.string.PinMmi); + } + } + + return ""; + } + + private void + onSetComplete(AsyncResult ar){ + StringBuilder sb = new StringBuilder(getScString()); + sb.append("\n"); + + if (ar.exception != null) { + state = State.FAILED; + if (ar.exception instanceof CommandException) { + CommandException.Error err = ((CommandException)(ar.exception)).getCommandError(); + if (err == CommandException.Error.PASSWORD_INCORRECT) { + if (isPukCommand()) { + sb.append(context.getText( + com.android.internal.R.string.badPuk)); + } else { + sb.append(context.getText( + com.android.internal.R.string.passwordIncorrect)); + } + } else { + sb.append(context.getText( + com.android.internal.R.string.mmiError)); + } + } else { + sb.append(context.getText( + com.android.internal.R.string.mmiError)); + } + } else if (isRegister()) { + state = State.COMPLETE; + sb.append(context.getText( + com.android.internal.R.string.serviceRegistered)); + } else { + state = State.FAILED; + sb.append(context.getText( + com.android.internal.R.string.mmiError)); + } + + message = sb; + phone.onMMIDone(this); + } + +} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index 425682a..e0c3a47 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -919,6 +919,9 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { case DATA_ACCESS_CDMA_EvDo_A: ret = "CDMA - EvDo rev. A"; break; + case DATA_ACCESS_CDMA_EvDo_B: + ret = "CDMA - EvDo rev. B"; + break; default: if (DBG) { Log.e(LOG_TAG, "Wrong network. Can not return a string."); @@ -1170,32 +1173,23 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { } else { int[] ints = (int[])ar.result; int offset = 2; - int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120; int cdmaEcio = (ints[offset+1] > 0) ? -ints[offset+1] : -160; + int evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -120; + int evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1; + int evdoSnr = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1; - int evdoRssi = -1; - int evdoEcio = -1; - int evdoSnr = -1; - if ((networkType == ServiceState.RADIO_TECHNOLOGY_EVDO_0) - || (networkType == ServiceState.RADIO_TECHNOLOGY_EVDO_A)) { - evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -120; - evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1; - evdoSnr = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1; - } - + //log(String.format("onSignalStrengthResult cdmaDbm=%d cdmaEcio=%d evdoRssi=%d evdoEcio=%d evdoSnr=%d", + // cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr)); mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr, false); } - if (!mSignalStrength.equals(oldSignalStrength)) { - try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after - // POLL_PERIOD_MILLIS) during Radio Technology Change) - phone.notifySignalStrength(); - } catch (NullPointerException ex) { - log("onSignalStrengthResult() Phone already destroyed: " + ex - + "SignalStrength not notified"); - } + try { + phone.notifySignalStrength(); + } catch (NullPointerException ex) { + log("onSignalStrengthResult() Phone already destroyed: " + ex + + "SignalStrength not notified"); } } @@ -1213,6 +1207,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { case 6: // RADIO_TECHNOLOGY_1xRTT case 7: // RADIO_TECHNOLOGY_EVDO_0 case 8: // RADIO_TECHNOLOGY_EVDO_A + case 12: // RADIO_TECHNOLOGY_EVDO_B retVal = ServiceState.STATE_IN_SERVICE; break; default: diff --git a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java b/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java index e7fbf6b..af2ad48 100644 --- a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java +++ b/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java @@ -25,6 +25,9 @@ package com.android.internal.telephony.gsm; * */ public interface CallFailCause { + // Unassigned/Unobtainable number + static final int UNOBTAINABLE_NUMBER = 1; + static final int NORMAL_CLEARING = 16; // Busy Tone static final int USER_BUSY = 17; diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java index a5188ce..b0de4f5 100755..100644 --- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java +++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java @@ -67,6 +67,7 @@ import com.android.internal.telephony.PhoneNotifier; import com.android.internal.telephony.PhoneProxy; import com.android.internal.telephony.PhoneSubInfo; import com.android.internal.telephony.TelephonyProperties; +import com.android.internal.telephony.UUSInfo; import com.android.internal.telephony.gsm.stk.StkService; import com.android.internal.telephony.test.SimulatedRadioControl; import com.android.internal.telephony.IccVmNotSupportedException; @@ -719,7 +720,12 @@ public class GSMPhone extends PhoneBase { } public Connection - dial (String dialString) throws CallStateException { + dial(String dialString) throws CallStateException { + return dial(dialString, null); + } + + public Connection + dial (String dialString, UUSInfo uusInfo) throws CallStateException { // Need to make sure dialString gets parsed properly String newDialString = PhoneNumberUtils.stripSeparators(dialString); @@ -735,9 +741,9 @@ public class GSMPhone extends PhoneBase { "dialing w/ mmi '" + mmi + "'..."); if (mmi == null) { - return mCT.dial(newDialString); + return mCT.dial(newDialString, uusInfo); } else if (mmi.isTemporaryModeCLIR()) { - return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode()); + return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode(), uusInfo); } else { mPendingMMIs.add(mmi); mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java index 91c089e..b82fefd 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java @@ -29,6 +29,7 @@ import com.android.internal.telephony.CallTracker; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.Connection; import com.android.internal.telephony.DriverCall; +import com.android.internal.telephony.UUSInfo; import com.android.internal.telephony.gsm.CallFailCause; import com.android.internal.telephony.gsm.GsmCall; import com.android.internal.telephony.gsm.GsmConnection; @@ -162,7 +163,7 @@ public final class GsmCallTracker extends CallTracker { * clirMode is one of the CLIR_ constants */ Connection - dial (String dialString, int clirMode) throws CallStateException { + dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException { // note that this triggers call state changed notif clearDisconnected(); @@ -208,7 +209,7 @@ public final class GsmCallTracker extends CallTracker { // Always unmute when initiating a new call setMute(false); - cm.dial(pendingMO.address, clirMode, obtainCompleteMessage()); + cm.dial(pendingMO.address, clirMode, uusInfo, obtainCompleteMessage()); } updatePhoneState(); @@ -217,10 +218,19 @@ public final class GsmCallTracker extends CallTracker { return pendingMO; } + Connection + dial(String dialString) throws CallStateException { + return dial(dialString, CommandsInterface.CLIR_DEFAULT, null); + } + + Connection + dial(String dialString, UUSInfo uusInfo) throws CallStateException { + return dial(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo); + } Connection - dial (String dialString) throws CallStateException { - return dial(dialString, CommandsInterface.CLIR_DEFAULT); + dial(String dialString, int clirMode) throws CallStateException { + return dial(dialString, clirMode, null); } void diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java index 445be39..0024c9b 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java @@ -73,6 +73,7 @@ public class GsmConnection extends Connection { DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED; PostDialState postDialState = PostDialState.NOT_STARTED; int numberPresentation = Connection.PRESENTATION_ALLOWED; + UUSInfo uusInfo; Handler h; @@ -126,6 +127,7 @@ public class GsmConnection extends Connection { isIncoming = dc.isMT; createTime = System.currentTimeMillis(); numberPresentation = dc.numberPresentation; + uusInfo = dc.uusInfo; this.index = index; @@ -356,6 +358,9 @@ public class GsmConnection extends Connection { case CallFailCause.FDN_BLOCKED: return DisconnectCause.FDN_BLOCKED; + case CallFailCause.UNOBTAINABLE_NUMBER: + return DisconnectCause.UNOBTAINABLE_NUMBER; + case CallFailCause.ERROR_UNSPECIFIED: case CallFailCause.NORMAL_CLEARING: default: @@ -728,4 +733,9 @@ public class GsmConnection extends Connection { public int getNumberPresentation() { return numberPresentation; } + + @Override + public UUSInfo getUUSInfo() { + return uusInfo; + } } diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java index bcbd127..cacf057 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java @@ -832,8 +832,7 @@ public final class GsmMmiCode extends Handler implements MmiCode { if (ar.exception != null) { state = State.FAILED; - message = context.getText( - com.android.internal.R.string.mmiError); + message = getErrorMessage(ar); phone.onMMIDone(this); } @@ -852,6 +851,19 @@ public final class GsmMmiCode extends Handler implements MmiCode { } //***** Private instance methods + private CharSequence getErrorMessage(AsyncResult ar) { + + if (ar.exception instanceof CommandException) { + CommandException.Error err = ((CommandException)(ar.exception)).getCommandError(); + if (err == CommandException.Error.FDN_CHECK_FAILURE) { + Log.i(LOG_TAG, "FDN_CHECK_FAILURE"); + return context.getText(com.android.internal.R.string.mmiFdnError); + } + } + + return context.getText(com.android.internal.R.string.mmiError); + } + private CharSequence getScString() { if (sc != null) { if (isServiceCodeCallBarring(sc)) { @@ -904,6 +916,9 @@ public final class GsmMmiCode extends Handler implements MmiCode { sb.append("\n"); sb.append(context.getText( com.android.internal.R.string.needPuk2)); + } else if (err == CommandException.Error.FDN_CHECK_FAILURE) { + Log.i(LOG_TAG, "FDN_CHECK_FAILURE"); + sb.append(context.getText(com.android.internal.R.string.mmiFdnError)); } else { sb.append(context.getText( com.android.internal.R.string.mmiError)); @@ -953,7 +968,7 @@ public final class GsmMmiCode extends Handler implements MmiCode { if (ar.exception != null) { state = State.FAILED; - sb.append(context.getText(com.android.internal.R.string.mmiError)); + sb.append(getErrorMessage(ar)); } else { int clirArgs[]; @@ -1123,7 +1138,7 @@ public final class GsmMmiCode extends Handler implements MmiCode { if (ar.exception != null) { state = State.FAILED; - sb.append(context.getText(com.android.internal.R.string.mmiError)); + sb.append(getErrorMessage(ar)); } else { CallForwardInfo infos[]; @@ -1175,7 +1190,7 @@ public final class GsmMmiCode extends Handler implements MmiCode { if (ar.exception != null) { state = State.FAILED; - sb.append(context.getText(com.android.internal.R.string.mmiError)); + sb.append(getErrorMessage(ar)); } else { int[] ints = (int[])ar.result; diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java index 6ae316d..d720516 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java @@ -94,6 +94,13 @@ final class GsmSMSDispatcher extends SMSDispatcher { SmsMessage sms = (SmsMessage) smsb; boolean handled = false; + if (sms.isTypeZero()) { + // As per 3GPP TS 23.040 9.2.3.9, Type Zero messages should not be + // Displayed/Stored/Notified. They should only be acknowledged. + Log.d(TAG, "Received short message type 0, Dont display or store it. Send Ack"); + return Intents.RESULT_SMS_HANDLED; + } + // Special case the message waiting indicator messages if (sms.isMWISetMessage()) { mGsmPhone.updateMessageWaitingIndicator(true); diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index d627baf..12c6b88 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java @@ -111,6 +111,14 @@ public class SmsMessage extends SmsMessageBase{ } /** + * 3GPP TS 23.040 9.2.3.9 specifies that Type Zero messages are indicated + * by TP_PID field set to value 0x40 + */ + public boolean isTypeZero() { + return (protocolIdentifier == 0x40); + } + + /** * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the * +CMT unsolicited response (PDU mode, of course) * +CMT: [<alpha>],<length><CR><LF><pdu> diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java index 11b3fd6..a120f52 100644 --- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java +++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java @@ -29,6 +29,7 @@ import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.DataCallState; import com.android.internal.telephony.IccCard; import com.android.internal.telephony.Phone; +import com.android.internal.telephony.UUSInfo; import com.android.internal.telephony.gsm.CallFailCause; import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo; import com.android.internal.telephony.gsm.SuppServiceNotification; @@ -496,6 +497,23 @@ public final class SimulatedCommands extends BaseCommands * retMsg.obj = AsyncResult ar * ar.exception carries exception on failure * ar.userObject contains the orignal value of result.obj + * ar.result is null on success and failure + * + * CLIR_DEFAULT == on "use subscription default value" + * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation) + * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation) + */ + public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) { + simulatedCallState.onDial(address); + + resultSuccess(result, null); + } + + /** + * returned message + * retMsg.obj = AsyncResult ar + * ar.exception carries exception on failure + * ar.userObject contains the orignal value of result.obj * ar.result is String containing IMSI on success */ public void getIMSI(Message result) { diff --git a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java index 20ea4d7..e14240f 100644 --- a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java +++ b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java @@ -82,6 +82,16 @@ public class PhoneNumberUtilsTest extends TestCase { assertEquals("17005550020", PhoneNumberUtils.calledPartyBCDToString(b, 0, 7)); + b[0] = (byte) 0x80; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55; + b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0; + assertEquals("17005550020", + PhoneNumberUtils.calledPartyBCDToString(b, 0, 7)); + + b[0] = (byte) 0x90; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55; + b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0; + assertEquals("+17005550020", + PhoneNumberUtils.calledPartyBCDToString(b, 0, 7)); + b[0] = (byte) 0x91; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55; b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0; assertEquals("+17005550020", diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/VelocityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/VelocityTest.java new file mode 100644 index 0000000..fb28e1e --- /dev/null +++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/VelocityTest.java @@ -0,0 +1,285 @@ +/* + * 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.frameworktest.view; + +import junit.framework.Assert; + +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; +import android.view.MotionEvent; +import android.view.VelocityTracker; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; +import android.view.animation.LinearInterpolator; + +/** + * Exercises {@link android.view.VelocityTracker} to compute correct velocity.<br> + * To launch this test, use :<br> + * <code>./development/testrunner/runtest.py framework -c com.android.frameworktest.view.VelocityTest</code> + */ +public class VelocityTest extends InstrumentationTestCase { + + @MediumTest + public void testInitialCondiditions() { + VelocityTracker vt = VelocityTracker.obtain(); + assertNotNull(vt); + vt.recycle(); + } + + /** + * Test that {@link android.view.VelocityTracker}.clear() clears + * the previous values after a call to computeCurrentVelocity() + */ + @MediumTest + public void testClear() { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 10, t, 300); + vt.computeCurrentVelocity(1); + assertFalse("Velocity should not be null", vt.getXVelocity() == 0.0f); + assertFalse("Velocity should not be null", vt.getYVelocity() == 0.0f); + vt.clear(); + vt.computeCurrentVelocity(1); + assertEquals(0.0f, vt.getXVelocity()); + assertEquals(0.0f, vt.getYVelocity()); + vt.recycle(); + } + + @MediumTest + public void testDragAcceleration () { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 15, t, 400, new AccelerateInterpolator()); + vt.computeCurrentVelocity(1000); + assertGreater(250.0f, vt.getXVelocity()); + assertGreater(250.0f, vt.getYVelocity()); + vt.recycle(); + } + + @MediumTest + public void testDragDeceleration () { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 15, t, 400, new DecelerateInterpolator()); + vt.computeCurrentVelocity(1000); + assertLower(250.0f, vt.getXVelocity()); + assertLower(250.0f, vt.getYVelocity()); + vt.recycle(); + } + + @MediumTest + public void testDragLinearHorizontal() { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + // 100px in 400ms => 250px/s + drag(vt, 100, 200, 200, 200, 15, t, 400); + vt.computeCurrentVelocity(1000); + assertEquals(0.0f, vt.getYVelocity()); + assertEqualFuzzy(250.0f, vt.getXVelocity(), 4f); + vt.recycle(); + } + + @MediumTest + public void testDragLinearVertical() { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + // 100px in 400ms => 250px/s + drag(vt, 200, 200, 100, 200, 15, t, 400); + vt.computeCurrentVelocity(1000); + assertEquals(0.0f, vt.getXVelocity()); + assertEqualFuzzy(250.0f, vt.getYVelocity(), 4f); + vt.recycle(); + } + + /** + * Test dragging with two points only + * (velocity must be an exact value) + */ + @MediumTest + public void testDragWith2Points () { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + // 100px, 2 steps, 100ms => 1000px/s + drag(vt, 100, 200, 100, 200, 2, t, 100); + vt.computeCurrentVelocity(1000); + assertEquals(1000.0f, vt.getXVelocity()); + assertEquals(1000.0f, vt.getYVelocity()); + vt.recycle(); + } + + /** + * Velocity is independent of the number of points used during + * the same interval + */ + @MediumTest + public void testStabilityInNbPoints () { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 10, t, 400); // 10 steps over 400ms + vt.computeCurrentVelocity(1); + float firstX = vt.getXVelocity(); + float firstY = vt.getYVelocity(); + vt.clear(); + drag(vt, 100, 200, 100, 200, 20, t, 400); // 20 steps over 400ms + vt.computeCurrentVelocity(1); + float secondX = vt.getXVelocity(); + float secondY = vt.getYVelocity(); + assertEqualFuzzy(firstX, secondX, 0.1f); + assertEqualFuzzy(firstY, secondY, 0.1f); + vt.recycle(); + } + + /** + * Velocity is independent of the time when the events occurs, + * it only depends on delays between the events. + */ + @MediumTest + public void testStabilityInTime () { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 10, t, 400); + vt.computeCurrentVelocity(1); + float firstX = vt.getXVelocity(); + float firstY = vt.getYVelocity(); + vt.clear(); + drag(vt, 100, 200, 100, 200, 10, t + 3600*1000, 400); // on hour later + vt.computeCurrentVelocity(1); + float secondX = vt.getXVelocity(); + float secondY = vt.getYVelocity(); + assertEqualFuzzy(firstX, secondX, 0.1f); + assertEqualFuzzy(firstY, secondY, 0.1f); + vt.recycle(); + } + + /** + * Velocity is independent of the position of the events, + * it only depends on their relative distance. + */ + @MediumTest + public void testStabilityInSpace () { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 10, t, 400); + vt.computeCurrentVelocity(1); + float firstX = vt.getXVelocity(); + float firstY = vt.getYVelocity(); + vt.clear(); + drag(vt, 200, 300, 200, 300, 10, t, 400); // 100px further + vt.computeCurrentVelocity(1); + float secondX = vt.getXVelocity(); + float secondY = vt.getYVelocity(); + assertEqualFuzzy(firstX, secondX, 0.1f); + assertEqualFuzzy(firstY, secondY, 0.1f); + vt.recycle(); + } + + /** + * Test that calls to {@link android.view.VelocityTracker}.computeCurrentVelocity() + * will output same values when using the same data. + */ + @MediumTest + public void testStabilityOfComputation() { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 10, t, 300); + vt.computeCurrentVelocity(1); + float firstX = vt.getXVelocity(); + float firstY = vt.getYVelocity(); + vt.computeCurrentVelocity(1); + float secondX = vt.getXVelocity(); + float secondY = vt.getYVelocity(); + assertEquals(firstX, secondX); + assertEquals(firstY, secondY); + vt.recycle(); + } + + /** + * Test the units parameter of {@link android.view.VelocityTracker}.computeCurrentVelocity() + */ + @MediumTest + public void testStabilityOfUnits() { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 10, t, 300); + vt.computeCurrentVelocity(1); + float firstX = vt.getXVelocity(); + float firstY = vt.getYVelocity(); + vt.computeCurrentVelocity(1000); + float secondX = vt.getXVelocity(); + float secondY = vt.getYVelocity(); + assertEqualFuzzy(firstX, secondX / 1000.0f, 0.1f); + assertEqualFuzzy(firstY, secondY / 1000.0f, 0.1f); + vt.recycle(); + } + + /** + * Simulate a drag by giving directly MotionEvents to + * the VelocityTracker using a linear interpolator + */ + private void drag(VelocityTracker vt, int startX, int endX, int startY, int endY, int steps, + long startime, int duration) { + drag(vt, startX, endX, startY, endY, steps, startime, duration, new LinearInterpolator()); + } + + /** + * Simulate a drag by giving directly MotionEvents to + * the VelocityTracker using a given interpolator + */ + private void drag(VelocityTracker vt, int startX, int endX, int startY, int endY, int steps, + long startime, int duration, Interpolator interpolator) { + addMotionEvent(vt, startX, startY, startime, MotionEvent.ACTION_DOWN); + float dt = duration / (float)steps; + int distX = endX - startX; + int distY = endY - startY; + for (int i=1; i<steps-1; i++) { + float ii = interpolator.getInterpolation(i / (float)steps); + int x = (int) (startX + distX * ii); + int y = (int) (startY + distY * ii); + long time = startime + (int) (i * dt); + addMotionEvent(vt, x, y, time, MotionEvent.ACTION_MOVE); + } + addMotionEvent(vt, endX, endY, startime + duration, MotionEvent.ACTION_UP); + } + + private void addMotionEvent(VelocityTracker vt, int x, int y, long time, int action) { + MotionEvent me = MotionEvent.obtain(time, time, action, x, y, 0); + vt.addMovement(me); + me.recycle(); + } + + /** + * Float imprecision of the average computations and filtering + * (removing last MotionEvent for N > 3) implies that tests + * accepts some approximated values. + */ + private void assertEqualFuzzy(float expected, float actual, float threshold) { + boolean fuzzyEqual = actual >= expected - threshold && actual <= expected + threshold; + Assert.assertTrue("Expected: <"+expected+"> but was: <"+actual+ + "> while accepting a variation of: <"+threshold+">", fuzzyEqual); + } + + private void assertGreater(float minExpected, float actual) { + Assert.assertTrue("Expected: minimum <"+minExpected+"> but was: <"+actual+">", + actual > minExpected); + } + + private void assertLower(float maxExpected, float actual) { + Assert.assertTrue("Expected: maximum <"+maxExpected+"> but was: <"+actual+">", + actual < maxExpected); + } +} diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h index 77df6e5..74d269d 100644 --- a/tools/aapt/Bundle.h +++ b/tools/aapt/Bundle.h @@ -39,7 +39,7 @@ public: mRequireLocalization(false), mPseudolocalize(false), mValues(false), mCompressionMethod(0), mOutputAPKFile(NULL), - mAssetSourceDir(NULL), mProguardFile(NULL), + mAutoAddOverlay(false), mAssetSourceDir(NULL), mProguardFile(NULL), mAndroidManifestFile(NULL), mPublicOutputFile(NULL), mRClassDir(NULL), mResourceIntermediatesDir(NULL), mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL), @@ -84,6 +84,8 @@ public: void setJunkPath(bool val) { mJunkPath = val; } const char* getOutputAPKFile() const { return mOutputAPKFile; } void setOutputAPKFile(const char* val) { mOutputAPKFile = val; } + bool getAutoAddOverlay() { return mAutoAddOverlay; } + void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; } /* * Input options. @@ -167,6 +169,7 @@ private: int mCompressionMethod; bool mJunkPath; const char* mOutputAPKFile; + bool mAutoAddOverlay; const char* mAssetSourceDir; const char* mProguardFile; const char* mAndroidManifestFile; diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp index 0b51ad8..1a4ec7a 100644 --- a/tools/aapt/Main.cpp +++ b/tools/aapt/Main.cpp @@ -60,6 +60,7 @@ void usage(void) " [--min-sdk-version VAL] [--target-sdk-version VAL] \\\n" " [--max-sdk-version VAL] [--app-version VAL] \\\n" " [--app-version-name TEXT] [--custom-package VAL] \\\n" + " [--auto-add-overlay] \\\n" " [-I base-package [-I base-package ...]] \\\n" " [-A asset-source-dir] [-G class-list-file] [-P public-definitions-file] \\\n" " [-S resource-sources [-S resource-sources ...]] " @@ -134,7 +135,9 @@ void usage(void) " --version-name\n" " inserts android:versionName in to manifest.\n" " --custom-package\n" - " generates R.java into a different package.\n"); + " generates R.java into a different package.\n" + " --auto-add-overlay\n" + " Automatically add resources that are only in overlays.\n"); } /* @@ -429,6 +432,8 @@ int main(int argc, char* const argv[]) goto bail; } bundle.setCustomPackage(argv[0]); + } else if (strcmp(cp, "-auto-add-overlay") == 0) { + bundle.setAutoAddOverlay(true); } else { fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp); wantUsage = true; diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index 19b9b01..b3cf7ea 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -1587,7 +1587,7 @@ status_t ResourceTable::startBag(const SourcePos& sourcePos, sourcePos.file.striing(), sourcePos.line, String8(type).string()); } #endif - if (overlay && !hasBagOrEntry(package, type, name)) { + if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) { bool canAdd = false; sp<Package> p = mPackages.valueFor(package); if (p != NULL) { @@ -3275,12 +3275,13 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, const SourcePos& sourcePos, const ResTable_config* config, bool doSetIndex, - bool overlay) + bool overlay, + bool autoAddOverlay) { int pos = -1; sp<ConfigList> c = mConfigs.valueFor(entry); if (c == NULL) { - if (overlay == true && mCanAddEntries.indexOf(entry) < 0) { + if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) { sourcePos.error("Resource at %s appears in overlay but not" " in the base package; use <add-resource> to add.\n", String8(entry).string()); @@ -3592,7 +3593,7 @@ sp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package, if (t == NULL) { return NULL; } - return t->getEntry(name, sourcePos, config, doSetIndex, overlay); + return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay()); } sp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID, diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h index caa01b3..3fff71c 100644 --- a/tools/aapt/ResourceTable.h +++ b/tools/aapt/ResourceTable.h @@ -424,7 +424,8 @@ public: const SourcePos& pos, const ResTable_config* config = NULL, bool doSetIndex = false, - bool overlay = false); + bool overlay = false, + bool autoAddOverlay = false); const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; } diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp index fc658f5..f17f66b 100644 --- a/tools/aidl/aidl.cpp +++ b/tools/aidl/aidl.cpp @@ -55,7 +55,7 @@ test_document(document_item_type* d) printf("parcelable %s %s;\n", b->package, b->name.data); } else { - printf("UNKNOWN d=0x%08x d->item_type=%ld\n", (long)d, d->item_type); + printf("UNKNOWN d=0x%08lx d->item_type=%d\n", (long)d, d->item_type); } d = d->next; } |