Merge "Add ALL CAPS style to TextView/TextAppearance"
diff --git a/api/14.txt b/api/14.txt
index 050540b..d25d2b9 100644
--- a/api/14.txt
+++ b/api/14.txt
@@ -16272,20 +16272,10 @@
 
   public class AllocationAdapter extends android.renderscript.Allocation {
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
-    method public void readData(int[]);
-    method public void readData(float[]);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
     method public void setY(int);
     method public void setZ(int);
-    method public void subData(int, android.renderscript.FieldPacker);
-    method public void subData1D(int, int, int[]);
-    method public void subData1D(int, int, short[]);
-    method public void subData1D(int, int, byte[]);
-    method public void subData1D(int, int, float[]);
-    method public void subData2D(int, int, int, int, int[]);
-    method public void subData2D(int, int, int, int, float[]);
-    method public void subElementData(int, int, android.renderscript.FieldPacker);
   }
 
    class BaseObj {
diff --git a/api/current.txt b/api/current.txt
index b240e14..d507940 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16682,23 +16682,12 @@
   }
 
   public class AllocationAdapter extends android.renderscript.Allocation {
+    method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
-    method public void readData(int[]);
-    method public void readData(float[]);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
     method public void setY(int);
     method public void setZ(int);
-    method public void subData(int, android.renderscript.FieldPacker);
-    method public void subData1D(int, int, int[]);
-    method public void subData1D(int, int, short[]);
-    method public void subData1D(int, int, byte[]);
-    method public void subData1D(int, int, float[]);
-    method public void subData1D(int, int, android.renderscript.AllocationAdapter, int);
-    method public void subData2D(int, int, int, int, int[]);
-    method public void subData2D(int, int, int, int, float[]);
-    method public void subData2D(int, int, int, int, android.renderscript.AllocationAdapter, int, int);
-    method public void subElementData(int, int, android.renderscript.FieldPacker);
   }
 
   public class BaseObj {
diff --git a/core/java/android/content/XmlDocumentProvider.java b/core/java/android/content/XmlDocumentProvider.java
deleted file mode 100644
index 76539c7..0000000
--- a/core/java/android/content/XmlDocumentProvider.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.methods.HttpGet;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import android.content.ContentResolver.OpenResourceIdResult;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.net.http.AndroidHttpClient;
-import android.util.Log;
-import android.widget.CursorAdapter;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.BitSet;
-import java.util.Stack;
-import java.util.regex.Pattern;
-
-/**
- * @hide -- not yet ready to support, should be provided just as a static lib.
- * 
- * A read-only content provider which extracts data out of an XML document.
- *
- * <p>A XPath-like selection pattern is used to select some nodes in the XML document. Each such
- * node will create a row in the {@link Cursor} result.</p>
- *
- * Each row is then populated with columns that are also defined as XPath-like projections. These
- * projections fetch attributes values or text in the matching row node or its children.
- *
- * <p>To add this provider in your application, you should add its declaration to your application
- * manifest:
- * <pre class="prettyprint">
- * &lt;provider android:name="android.content.XmlDocumentProvider" android:authorities="xmldocument" /&gt;
- * </pre>
- * </p>
- *
- * <h2>Node selection syntax</h2>
- * The node selection syntax is made of the concatenation of an arbitrary number (at least one) of
- * <code>/node_name</code> node selection patterns.
- *
- * <p>The <code>/root/child1/child2</code> pattern will for instance match all nodes named
- * <code>child2</code> which are children of a node named <code>child1</code> which are themselves
- * children of a root node named <code>root</code>.</p>
- *
- * Any <code>/</code> separator in the previous expression can be replaced by a <code>//</code>
- * separator instead, which indicated a <i>descendant</i> instead of a child.
- *
- * <p>The <code>//node1//node2</code> pattern will for instance match all nodes named
- * <code>node2</code> which are descendant of a node named <code>node1</code> located anywhere in
- * the document hierarchy.</p>
- *
- * Node names can contain namespaces in the form <code>namespace:node</code>.
- *
- * <h2>Projection syntax</h2>
- * For every selected node, the projection will then extract actual data from this node and its
- * descendant.
- *
- * <p>Use a syntax similar to the selection syntax described above to select the text associated
- * with a child of the selected node. The implicit root of this projection pattern is the selected
- * node. <code>/</code> will hence refer to the text of the selected node, while
- * <code>/child1</code> will fetch the text of its child named <code>child1</code> and
- * <code>//child1</code> will match any <i>descendant</i> named <code>child1</code>. If several
- * nodes match the projection pattern, their texts are appended as a result.</p>
- *
- * A projection can also fetch any node attribute by appending a <code>@attribute_name</code>
- * pattern to the previously described syntax. <code>//child1@price</code> will for instance match
- * the attribute <code>price</code> of any <code>child1</code> descendant.
- *
- * <p>If a projection does not match any node/attribute, its associated value will be an empty
- * string.</p>
- *
- * <h2>Example</h2>
- * Using the following XML document:
- * <pre class="prettyprint">
- * &lt;library&gt;
- *   &lt;book id="EH94"&gt;
- *     &lt;title&gt;The Old Man and the Sea&lt;/title&gt;
- *     &lt;author&gt;Ernest Hemingway&lt;/author&gt;
- *   &lt;/book&gt;
- *   &lt;book id="XX10"&gt;
- *     &lt;title&gt;The Arabian Nights: Tales of 1,001 Nights&lt;/title&gt;
- *   &lt;/book&gt;
- *   &lt;no-id&gt;
- *     &lt;book&gt;
- *       &lt;title&gt;Animal Farm&lt;/title&gt;
- *       &lt;author&gt;George Orwell&lt;/author&gt;
- *     &lt;/book&gt;
- *   &lt;/no-id&gt;
- * &lt;/library&gt;
- * </pre>
- * A selection pattern of <code>/library//book</code> will match the three book entries (while
- * <code>/library/book</code> will only match the first two ones).
- *
- * <p>Defining the projections as <code>/title</code>, <code>/author</code> and <code>@id</code>
- * will retrieve the associated data. Note that the author of the second book as well as the id of
- * the third are empty strings.
- */
-public class XmlDocumentProvider extends ContentProvider {
-    /*
-     * Ideas for improvement:
-     * - Expand XPath-like syntax to allow for [nb] child number selector
-     * - Address the starting . bug in AbstractCursor which prevents a true XPath syntax.
-     * - Provide an alternative to concatenation when several node match (list-like).
-     * - Support namespaces in attribute names.
-     * - Incremental Cursor creation, pagination
-     */
-    private static final String LOG_TAG = "XmlDocumentProvider";
-    private AndroidHttpClient mHttpClient;
-
-    @Override
-    public boolean onCreate() {
-        return true;
-    }
-
-    /**
-     * Query data from the XML document referenced in the URI.
-     *
-     * <p>The XML document can be a local resource or a file that will be downloaded from the
-     * Internet. In the latter case, your application needs to request the INTERNET permission in
-     * its manifest.</p>
-     *
-     * The URI will be of the form <code>content://xmldocument/?resource=R.xml.myFile</code> for a
-     * local resource. <code>xmldocument</code> should match the authority declared for this
-     * provider in your manifest. Internet documents are referenced using
-     * <code>content://xmldocument/?url=</code> followed by an encoded version of the URL of your
-     * document (see {@link Uri#encode(String)}).
-     *
-     * <p>The number of columns of the resulting Cursor is equal to the size of the projection
-     * array plus one, named <code>_id</code> which will contain a unique row id (allowing the
-     * Cursor to be used with a {@link CursorAdapter}). The other columns' names are the projection
-     * patterns.</p>
-     *
-     * @param uri The URI of your local resource or Internet document.
-     * @param projection A set of patterns that will be used to extract data from each selected
-     * node. See class documentation for pattern syntax.
-     * @param selection A selection pattern which will select the nodes that will create the
-     * Cursor's rows. See class documentation for pattern syntax.
-     * @param selectionArgs This parameter is ignored.
-     * @param sortOrder The row order in the resulting cursor is determined from the node order in
-     * the XML document. This parameter is ignored.
-     * @return A Cursor or null in case of error.
-     */
-    @Override
-    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-            String sortOrder) {
-
-        XmlPullParser parser = null;
-        mHttpClient = null;
-
-        final String url = uri.getQueryParameter("url");
-        if (url != null) {
-            parser = getUriXmlPullParser(url);
-        } else {
-            final String resource = uri.getQueryParameter("resource");
-            if (resource != null) {
-                Uri resourceUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
-                        getContext().getPackageName() + "/" + resource);
-                parser = getResourceXmlPullParser(resourceUri);
-            }
-        }
-
-        if (parser != null) {
-            XMLCursor xmlCursor = new XMLCursor(selection, projection);
-            try {
-                xmlCursor.parseWith(parser);
-                return xmlCursor;
-            } catch (IOException e) {
-                Log.w(LOG_TAG, "I/O error while parsing XML " + uri, e);
-            } catch (XmlPullParserException e) {
-                Log.w(LOG_TAG, "Error while parsing XML " + uri, e);
-            } finally {
-                if (mHttpClient != null) {
-                    mHttpClient.close();
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Creates an XmlPullParser for the provided URL. Can be overloaded to provide your own parser.
-     * @param url The URL of the XML document that is to be parsed.
-     * @return An XmlPullParser on this document.
-     */
-    protected XmlPullParser getUriXmlPullParser(String url) {
-        XmlPullParser parser = null;
-        try {
-            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
-            factory.setNamespaceAware(true);
-            parser = factory.newPullParser();
-        } catch (XmlPullParserException e) {
-            Log.e(LOG_TAG, "Unable to create XmlPullParser", e);
-            return null;
-        }
-
-        InputStream inputStream = null;
-        try {
-            final HttpGet get = new HttpGet(url);
-            mHttpClient = AndroidHttpClient.newInstance("Android");
-            HttpResponse response = mHttpClient.execute(get);
-            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
-                final HttpEntity entity = response.getEntity();
-                if (entity != null) {
-                    inputStream = entity.getContent();
-                }
-            }
-        } catch (IOException e) {
-            Log.w(LOG_TAG, "Error while retrieving XML file " + url, e);
-            return null;
-        }
-
-        try {
-            parser.setInput(inputStream, null);
-        } catch (XmlPullParserException e) {
-            Log.w(LOG_TAG, "Error while reading XML file from " + url, e);
-            return null;
-        }
-
-        return parser;
-    }
-
-    /**
-     * Creates an XmlPullParser for the provided local resource. Can be overloaded to provide your
-     * own parser.
-     * @param resourceUri A fully qualified resource name referencing a local XML resource.
-     * @return An XmlPullParser on this resource.
-     */
-    protected XmlPullParser getResourceXmlPullParser(Uri resourceUri) {
-        OpenResourceIdResult resourceId;
-        try {
-            resourceId = getContext().getContentResolver().getResourceId(resourceUri);
-            return resourceId.r.getXml(resourceId.id);
-        } catch (FileNotFoundException e) {
-            Log.w(LOG_TAG, "XML resource not found: " + resourceUri.toString(), e);
-            return null;
-        }
-    }
-
-    /**
-     * Returns "vnd.android.cursor.dir/xmldoc".
-     */
-    @Override
-    public String getType(Uri uri) {
-        return "vnd.android.cursor.dir/xmldoc";
-    }
-
-    /**
-     * This ContentProvider is read-only. This method throws an UnsupportedOperationException.
-     **/
-    @Override
-    public Uri insert(Uri uri, ContentValues values) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * This ContentProvider is read-only. This method throws an UnsupportedOperationException.
-     **/
-    @Override
-    public int delete(Uri uri, String selection, String[] selectionArgs) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * This ContentProvider is read-only. This method throws an UnsupportedOperationException.
-     **/
-    @Override
-    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-        throw new UnsupportedOperationException();
-    }
-
-    private static class XMLCursor extends MatrixCursor {
-        private final Pattern mSelectionPattern;
-        private Pattern[] mProjectionPatterns;
-        private String[] mAttributeNames;
-        private String[] mCurrentValues;
-        private BitSet[] mActiveTextDepthMask;
-        private final int mNumberOfProjections;
-
-        public XMLCursor(String selection, String[] projections) {
-            super(projections);
-            // The first column in projections is used for the _ID
-            mNumberOfProjections = projections.length - 1;
-            mSelectionPattern = createPattern(selection);
-            createProjectionPattern(projections);
-        }
-
-        private Pattern createPattern(String input) {
-            String pattern = input.replaceAll("//", "/(.*/|)").replaceAll("^/", "^/") + "$";
-            return Pattern.compile(pattern);
-        }
-
-        private void createProjectionPattern(String[] projections) {
-            mProjectionPatterns = new Pattern[mNumberOfProjections];
-            mAttributeNames = new String[mNumberOfProjections];
-            mActiveTextDepthMask = new BitSet[mNumberOfProjections];
-            // Add a column to store _ID
-            mCurrentValues = new String[mNumberOfProjections + 1];
-
-            for (int i=0; i<mNumberOfProjections; i++) {
-                mActiveTextDepthMask[i] = new BitSet();
-                String projection = projections[i + 1]; // +1 to skip the _ID column
-                int atIndex = projection.lastIndexOf('@', projection.length());
-                if (atIndex >= 0) {
-                    mAttributeNames[i] = projection.substring(atIndex+1);
-                    projection = projection.substring(0, atIndex);
-                } else {
-                    mAttributeNames[i] = null;
-                }
-
-                // Conforms to XPath standard: reference to local context starts with a .
-                if (projection.charAt(0) == '.') {
-                    projection = projection.substring(1);
-                }
-                mProjectionPatterns[i] = createPattern(projection);
-            }
-        }
-
-        public void parseWith(XmlPullParser parser) throws IOException, XmlPullParserException {
-            StringBuilder path = new StringBuilder();
-            Stack<Integer> pathLengthStack = new Stack<Integer>();
-
-            // There are two parsing mode: in root mode, rootPath is updated and nodes matching
-            // selectionPattern are searched for and currentNodeDepth is negative.
-            // When a node matching selectionPattern is found, currentNodeDepth is set to 0 and
-            // updated as children are parsed and projectionPatterns are searched in nodePath.
-            int currentNodeDepth = -1;
-
-            // Index where local selected node path starts from in path
-            int currentNodePathStartIndex = 0;
-
-            int eventType = parser.getEventType();
-            while (eventType != XmlPullParser.END_DOCUMENT) {
-
-                if (eventType == XmlPullParser.START_TAG) {
-                    // Update path
-                    pathLengthStack.push(path.length());
-                    path.append('/');
-                    String prefix = null;
-                    try {
-                        // getPrefix is not supported by local Xml resource parser
-                        prefix = parser.getPrefix();
-                    } catch (RuntimeException e) {
-                        prefix = null;
-                    }
-                    if (prefix != null) {
-                        path.append(prefix);
-                        path.append(':');
-                    }
-                    path.append(parser.getName());
-
-                    if (currentNodeDepth >= 0) {
-                        currentNodeDepth++;
-                    } else {
-                        // A node matching selection is found: initialize child parsing mode
-                        if (mSelectionPattern.matcher(path.toString()).matches()) {
-                            currentNodeDepth = 0;
-                            currentNodePathStartIndex = path.length();
-                            mCurrentValues[0] = Integer.toString(getCount()); // _ID
-                            for (int i = 0; i < mNumberOfProjections; i++) {
-                                // Reset values to default (empty string)
-                                mCurrentValues[i + 1] = "";
-                                mActiveTextDepthMask[i].clear();
-                            }
-                        }
-                    }
-
-                    // This test has to be separated from the previous one as currentNodeDepth can
-                    // be modified above (when a node matching selection is found).
-                    if (currentNodeDepth >= 0) {
-                        final String localNodePath = path.substring(currentNodePathStartIndex);
-                        for (int i = 0; i < mNumberOfProjections; i++) {
-                            if (mProjectionPatterns[i].matcher(localNodePath).matches()) {
-                                String attribute = mAttributeNames[i];
-                                if (attribute != null) {
-                                    mCurrentValues[i + 1] =
-                                        parser.getAttributeValue(null, attribute);
-                                } else {
-                                    mActiveTextDepthMask[i].set(currentNodeDepth, true);
-                                }
-                            }
-                        }
-                    }
-
-                } else if (eventType == XmlPullParser.END_TAG) {
-                    // Pop last node from path
-                    final int length = pathLengthStack.pop();
-                    path.setLength(length);
-
-                    if (currentNodeDepth >= 0) {
-                        if (currentNodeDepth == 0) {
-                            // Leaving a selection matching node: add a new row with results
-                            addRow(mCurrentValues);
-                        } else {
-                            for (int i = 0; i < mNumberOfProjections; i++) {
-                                mActiveTextDepthMask[i].set(currentNodeDepth, false);
-                            }
-                        }
-                        currentNodeDepth--;
-                    }
-
-                } else if ((eventType == XmlPullParser.TEXT) && (!parser.isWhitespace())) {
-                    for (int i = 0; i < mNumberOfProjections; i++) {
-                        if ((currentNodeDepth >= 0) &&
-                            (mActiveTextDepthMask[i].get(currentNodeDepth))) {
-                            mCurrentValues[i + 1] += parser.getText();
-                        }
-                    }
-                }
-
-                eventType = parser.next();
-            }
-        }
-    }
-}
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index b6c5522..4987e2f 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -246,8 +246,19 @@
         return nIsBackBufferPreserved();
     }
 
-    private static native boolean nIsBackBufferPreserved();    
-    
+    private static native boolean nIsBackBufferPreserved();
+
+    /**
+     * Disables v-sync. For performance testing only.
+     * 
+     * @hide
+     */
+    public static void disableVsync() {
+        nDisableVsync();
+    }
+
+    private static native void nDisableVsync();
+
     @Override
     void onPreDraw(Rect dirty) {
         if (dirty != null) {
@@ -265,7 +276,7 @@
     void onPostDraw() {
         nFinish(mRenderer);
     }
-    
+
     private static native void nFinish(int renderer);
 
     @Override
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index bbfb4c1..188970c 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -57,6 +57,16 @@
      * "false", to disable partial invalidates
      */
     static final String RENDER_DIRTY_REGIONS_PROPERTY = "hwui.render_dirty_regions";
+    
+    /**
+     * System property used to enable or disable vsync.
+     * The default value of this property is assumed to be false.
+     * 
+     * Possible values:
+     * "true", to disable vsync
+     * "false", to enable vsync
+     */
+    static final String DISABLE_VSYNC_PROPERTY = "hwui.disable_vsync";
 
     /**
      * Turn on to draw dirty regions every other frame.
@@ -303,6 +313,7 @@
 
         boolean mDirtyRegions;
         final boolean mDirtyRegionsRequested;
+        final boolean mVsyncDisabled;
 
         final int mGlVersion;
         final boolean mTranslucent;
@@ -314,10 +325,17 @@
         GlRenderer(int glVersion, boolean translucent) {
             mGlVersion = glVersion;
             mTranslucent = translucent;
+
             final String dirtyProperty = SystemProperties.get(RENDER_DIRTY_REGIONS_PROPERTY, "true");
             //noinspection PointlessBooleanExpression,ConstantConditions
             mDirtyRegions = RENDER_DIRTY_REGIONS && "true".equalsIgnoreCase(dirtyProperty);
             mDirtyRegionsRequested = mDirtyRegions;
+
+            final String vsyncProperty = SystemProperties.get(DISABLE_VSYNC_PROPERTY, "false");
+            mVsyncDisabled = "true".equalsIgnoreCase(vsyncProperty);
+            if (mVsyncDisabled) {
+                Log.d(LOG_TAG, "Disabling v-sync");
+            }
         }
 
         /**
@@ -765,6 +783,14 @@
         }
 
         @Override
+        void setup(int width, int height) {
+            super.setup(width, height);
+            if (mVsyncDisabled) {
+                GLES20Canvas.disableVsync();
+            }
+        }
+
+        @Override
         DisplayList createDisplayList(View v) {
             return new GLES20DisplayList(v);
         }
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 72263a7..88f59d4 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -2881,10 +2881,6 @@
             msg.append(", id[").append(i).append("]=").append(getPointerId(i));
             msg.append(", x[").append(i).append("]=").append(getX(i));
             msg.append(", y[").append(i).append("]=").append(getY(i));
-            msg.append(", pressure[").append(i).append("]=").append(getPressure(i));
-            msg.append(", touchMajor[").append(i).append("]=").append(getTouchMajor(i));
-            msg.append(", touchMinor[").append(i).append("]=").append(getTouchMinor(i));
-            msg.append(", orientation[").append(i).append("]=").append(getOrientation(i));
             msg.append(", toolType[").append(i).append("]=").append(
                     toolTypeToString(getToolType(i)));
         }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index ffa52d1..7ba86a5 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3467,40 +3467,6 @@
         return Math.min(duration, MAX_DURATION);
     }
 
-
-    // Helper to build a TouchEventData object from a MotionEvent object.
-    // A few fields are allocated now but will be set later:
-    //     mAction, mPoints and mPointsInView.
-    private static TouchEventData buildTouchFromEvent(MotionEvent ev) {
-        TouchEventData ted = new TouchEventData();
-        ted.mAction = ev.getActionMasked();
-        ted.mEventTime = ev.getEventTime();
-
-        final int count = ev.getPointerCount();
-        ted.mIds = new int[count];
-        ted.mPoints = new Point[count];
-        ted.mPointsInView = new Point[count];
-        ted.mPressures = new float[count];
-        ted.mTouchMajor = new int[count];
-        ted.mTouchMinor = new int[count];
-        ted.mOrientation = new float[count];
-        for (int c = 0; c < count; c++) {
-            ted.mIds[c] = ev.getPointerId(c);
-            ted.mPressures[c] = ev.getPressure(c);
-            ted.mTouchMajor[c] = (int) ev.getTouchMajor(c);
-            ted.mTouchMinor[c] = (int) ev.getTouchMinor(c);
-            ted.mOrientation[c] = ev.getOrientation(c);
-        }
-
-        if (ted.mAction == MotionEvent.ACTION_POINTER_DOWN
-            || ted.mAction == MotionEvent.ACTION_POINTER_UP) {
-            ted.mActionIndex = ev.getActionIndex();
-        }
-        ted.mMetaState = ev.getMetaState();
-
-        return ted;
-    }
-
     // helper to pin the scrollBy parameters (already in view coordinates)
     // returns true if the scroll was changed
     private boolean pinScrollBy(int dx, int dy, boolean animate, int animationDuration) {
@@ -5899,10 +5865,15 @@
                     }
                     // pass the touch events from UI thread to WebCore thread
                     if (shouldForwardTouchEvent()) {
-                        TouchEventData ted = buildTouchFromEvent(ev);
+                        TouchEventData ted = new TouchEventData();
                         ted.mAction = action;
+                        ted.mIds = new int[1];
+                        ted.mIds[0] = ev.getPointerId(0);
+                        ted.mPoints = new Point[1];
                         ted.mPoints[0] = new Point(contentX, contentY);
+                        ted.mPointsInView = new Point[1];
                         ted.mPointsInView[0] = new Point(x, y);
+                        ted.mMetaState = ev.getMetaState();
                         ted.mReprocess = mDeferTouchProcess;
                         ted.mNativeLayer = nativeScrollableLayer(
                                 contentX, contentY, ted.mNativeLayerRect, null);
@@ -5944,10 +5915,15 @@
                 // pass the touch events from UI thread to WebCore thread
                 if (shouldForwardTouchEvent() && mConfirmMove && (firstMove
                         || eventTime - mLastSentTouchTime > mCurrentTouchInterval)) {
-                    TouchEventData ted = buildTouchFromEvent(ev);
+                    TouchEventData ted = new TouchEventData();
                     ted.mAction = action;
+                    ted.mIds = new int[1];
+                    ted.mIds[0] = ev.getPointerId(0);
+                    ted.mPoints = new Point[1];
                     ted.mPoints[0] = new Point(contentX, contentY);
+                    ted.mPointsInView = new Point[1];
                     ted.mPointsInView[0] = new Point(x, y);
+                    ted.mMetaState = ev.getMetaState();
                     ted.mReprocess = mDeferTouchProcess;
                     ted.mNativeLayer = mScrollingLayer;
                     ted.mNativeLayerRect.set(mScrollingLayerRect);
@@ -6117,10 +6093,15 @@
                 if (!isFocused()) requestFocus();
                 // pass the touch events from UI thread to WebCore thread
                 if (shouldForwardTouchEvent()) {
-                    TouchEventData ted = buildTouchFromEvent(ev);
+                    TouchEventData ted = new TouchEventData();
+                    ted.mIds = new int[1];
+                    ted.mIds[0] = ev.getPointerId(0);
                     ted.mAction = action;
+                    ted.mPoints = new Point[1];
                     ted.mPoints[0] = new Point(contentX, contentY);
+                    ted.mPointsInView = new Point[1];
                     ted.mPointsInView[0] = new Point(x, y);
+                    ted.mMetaState = ev.getMetaState();
                     ted.mReprocess = mDeferTouchProcess;
                     ted.mNativeLayer = mScrollingLayer;
                     ted.mNativeLayerRect.set(mScrollingLayerRect);
@@ -6137,10 +6118,15 @@
                         mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
                         mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
                         if (inFullScreenMode() || mDeferTouchProcess) {
-                            TouchEventData ted = buildTouchFromEvent(ev);
+                            TouchEventData ted = new TouchEventData();
+                            ted.mIds = new int[1];
+                            ted.mIds[0] = ev.getPointerId(0);
                             ted.mAction = WebViewCore.ACTION_DOUBLETAP;
+                            ted.mPoints = new Point[1];
                             ted.mPoints[0] = new Point(contentX, contentY);
+                            ted.mPointsInView = new Point[1];
                             ted.mPointsInView[0] = new Point(x, y);
+                            ted.mMetaState = ev.getMetaState();
                             ted.mReprocess = mDeferTouchProcess;
                             ted.mNativeLayer = nativeScrollableLayer(
                                     contentX, contentY,
@@ -6272,14 +6258,24 @@
     }
 
     private void passMultiTouchToWebKit(MotionEvent ev, long sequence) {
-        TouchEventData ted = buildTouchFromEvent(ev);
-        for (int c = 0; c < ev.getPointerCount(); c++) {
+        TouchEventData ted = new TouchEventData();
+        ted.mAction = ev.getActionMasked();
+        final int count = ev.getPointerCount();
+        ted.mIds = new int[count];
+        ted.mPoints = new Point[count];
+        ted.mPointsInView = new Point[count];
+        for (int c = 0; c < count; c++) {
             ted.mIds[c] = ev.getPointerId(c);
             int x = viewToContentX((int) ev.getX(c) + mScrollX);
             int y = viewToContentY((int) ev.getY(c) + mScrollY);
             ted.mPoints[c] = new Point(x, y);
             ted.mPointsInView[c] = new Point((int) ev.getX(c), (int) ev.getY(c));
         }
+        if (ted.mAction == MotionEvent.ACTION_POINTER_DOWN
+            || ted.mAction == MotionEvent.ACTION_POINTER_UP) {
+            ted.mActionIndex = ev.getActionIndex();
+        }
+        ted.mMetaState = ev.getMetaState();
         ted.mReprocess = true;
         ted.mMotionEvent = MotionEvent.obtain(ev);
         ted.mSequence = sequence;
@@ -6353,11 +6349,7 @@
             if (removeEvents) {
                 mWebViewCore.removeMessages(EventHub.TOUCH_EVENT);
             }
-
             TouchEventData ted = new TouchEventData();
-            ted.mAction = MotionEvent.ACTION_CANCEL;
-            ted.mEventTime = mLastTouchTime;
-            ted.mMetaState = 0;
             ted.mIds = new int[1];
             ted.mIds[0] = 0;
             ted.mPoints = new Point[1];
@@ -6366,15 +6358,7 @@
             int viewX = contentToViewX(x) - mScrollX;
             int viewY = contentToViewY(y) - mScrollY;
             ted.mPointsInView[0] = new Point(viewX, viewY);
-            ted.mPressures = new float[1];
-            ted.mPressures[0] = 1;
-            ted.mTouchMajor = new int[1];
-            ted.mTouchMajor[0] = 1;
-            ted.mTouchMinor = new int[1];
-            ted.mTouchMinor[0] = 1;
-            ted.mOrientation = new float[1];
-            ted.mOrientation[0] = 0;
-
+            ted.mAction = MotionEvent.ACTION_CANCEL;
             ted.mNativeLayer = nativeScrollableLayer(
                     x, y, ted.mNativeLayerRect, null);
             ted.mSequence = mTouchEventQueue.nextTouchSequence();
@@ -8053,7 +8037,6 @@
                     if (inFullScreenMode() || mDeferTouchProcess) {
                         TouchEventData ted = new TouchEventData();
                         ted.mAction = WebViewCore.ACTION_LONGPRESS;
-                        ted.mEventTime = mLastTouchTime;
                         ted.mIds = new int[1];
                         ted.mIds[0] = 0;
                         ted.mPoints = new Point[1];
@@ -8061,15 +8044,6 @@
                                                    viewToContentY(mLastTouchY + mScrollY));
                         ted.mPointsInView = new Point[1];
                         ted.mPointsInView[0] = new Point(mLastTouchX, mLastTouchY);
-                        ted.mPressures = new float[1];
-                        ted.mPressures[0] = 1;
-                        ted.mTouchMajor = new int[1];
-                        ted.mTouchMajor[0] = 1;
-                        ted.mTouchMinor = new int[1];
-                        ted.mTouchMinor[0] = 1;
-                        ted.mOrientation = new float[1];
-                        ted.mOrientation[0] = 0;
-
                         // metaState for long press is tricky. Should it be the
                         // state when the press started or when the press was
                         // released? Or some intermediary key state? For
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 3357220..2145edd 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -577,10 +577,8 @@
     private native void nativeTouchUp(int touchGeneration,
             int framePtr, int nodePtr, int x, int y);
 
-    private native boolean nativeHandleTouchEvent(int action, long eventTime,
-            int[] idArray, int[] xArray, int[] yArray, float[] pressureArray,
-            int[] touchMajorArray, int[] touchMinorArray, float[] orientationArray,
-            int count, int actionIndex, int metaState);
+    private native boolean nativeHandleTouchEvent(int action, int[] idArray,
+            int[] xArray, int[] yArray, int count, int actionIndex, int metaState);
 
     private native void nativeUpdateFrameCache();
 
@@ -835,21 +833,16 @@
 
     static class TouchEventData {
         int mAction;
-        long mEventTime;  // Time (in ms) this event was generated.
-        int[] mIds;  // Ids of the touch points.
+        int[] mIds;  // Ids of the touch points
         Point[] mPoints;
-        Point[] mPointsInView;  // Point coordinates in view axis.
-        float[] mPressures;  // Pressures of the touch points.
-        int[] mTouchMajor;  // Length of the major axis of the touch area.
-        int[] mTouchMinor;  // Length of the minor axis of the touch area.
-        float[] mOrientation;  // The orientation of the touch area.
-        int mActionIndex;  // Associated pointer index for ACTION_POINTER_DOWN/UP.
+        Point[] mPointsInView;  // the point coordinates in view axis.
+        int mActionIndex;  // Associated pointer index for ACTION_POINTER_DOWN/UP
         int mMetaState;
         boolean mReprocess;
-        MotionEvent mMotionEvent;  // Only used for multi-touch.
+        MotionEvent mMotionEvent;
         int mNativeLayer;
         Rect mNativeLayerRect = new Rect();
-        long mSequence;  // For queuing the events.
+        long mSequence;
         boolean mNativeResult;
     }
 
@@ -1358,11 +1351,8 @@
                                 nativeScrollLayer(ted.mNativeLayer,
                                         ted.mNativeLayerRect);
                             }
-                            ted.mNativeResult = nativeHandleTouchEvent(
-                                    ted.mAction, ted.mEventTime, ted.mIds,
-                                    xArray, yArray, ted.mPressures,
-                                    ted.mTouchMajor, ted.mTouchMinor, ted.mOrientation,
-                                    count, ted.mActionIndex, ted.mMetaState);
+                            ted.mNativeResult = nativeHandleTouchEvent(ted.mAction, ted.mIds,
+                                    xArray, yArray, count, ted.mActionIndex, ted.mMetaState);
                             Message.obtain(
                                     mWebView.mPrivateHandler,
                                     WebView.PREVENT_TOUCH_ID,
@@ -2245,13 +2235,8 @@
 
     // called by JNI
     private void updateViewport() {
-        // if updateViewport is called before first layout, wait until first
-        // layout to update the viewport. In the rare case, this is called after
-        // first layout, force an update as we have just parsed the viewport
-        // meta tag.
-        if (mBrowserFrame.firstLayoutDone()) {
-            setupViewport(true);
-        }
+        // Update viewport asap to make sure we get correct one.
+        setupViewport(true);
     }
 
     private void setupViewport(boolean updateViewState) {
@@ -2385,8 +2370,12 @@
                         (float) webViewWidth / mViewportWidth;
             } else {
                 mInitialViewState.mTextWrapScale = adjust;
-                // 0 will trigger WebView to turn on zoom overview mode
-                mInitialViewState.mViewScale = 0;
+                if (mSettings.getUseWideViewPort()) {
+                    // 0 will trigger WebView to turn on zoom overview mode
+                    mInitialViewState.mViewScale = 0;
+                } else {
+                    mInitialViewState.mViewScale = adjust;
+                }
             }
         }
 
@@ -2417,7 +2406,7 @@
             mEventHub.removeMessages(EventHub.VIEW_SIZE_CHANGED);
             mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null,
                     EventHub.VIEW_SIZE_CHANGED, data));
-        } else if (mSettings.getUseWideViewPort()) {
+        } else {
             if (viewportWidth == 0) {
                 // Trick to ensure VIEW_SIZE_CHANGED will be sent from WebView
                 // to WebViewCore
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 2106eb4..681f43f 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -115,6 +115,18 @@
     return error == EGL_SUCCESS && value == EGL_BUFFER_PRESERVED;
 }
 
+static void android_view_GLES20Canvas_disableVsync(JNIEnv* env, jobject clazz) {
+    EGLDisplay display = eglGetCurrentDisplay();
+
+    eglGetError();
+    eglSwapInterval(display, 0);
+
+    EGLint error = eglGetError();
+    if (error != EGL_SUCCESS) {
+        RENDERER_LOGD("Could not disable v-sync (%x)", error);
+    }
+}
+
 // ----------------------------------------------------------------------------
 // Constructors
 // ----------------------------------------------------------------------------
@@ -621,7 +633,7 @@
 
     if (layer) {
         jint* storage = env->GetIntArrayElements(layerInfo, NULL);
-        storage[0] = layer->texture;
+        storage[0] = layer->getTexture();
         env->ReleaseIntArrayElements(layerInfo, storage, 0);
     }
 
@@ -634,8 +646,8 @@
 
     if (layer) {
         jint* storage = env->GetIntArrayElements(layerInfo, NULL);
-        storage[0] = layer->width;
-        storage[1] = layer->height;
+        storage[0] = layer->getWidth();
+        storage[1] = layer->getHeight();
         env->ReleaseIntArrayElements(layerInfo, storage, 0);
     }
 
@@ -647,8 +659,8 @@
     LayerRenderer::resizeLayer(layer, width, height);
 
     jint* storage = env->GetIntArrayElements(layerInfo, NULL);
-    storage[0] = layer->width;
-    storage[1] = layer->height;
+    storage[0] = layer->getWidth();
+    storage[1] = layer->getHeight();
     env->ReleaseIntArrayElements(layerInfo, storage, 0);
 }
 
@@ -722,6 +734,7 @@
 #ifdef USE_OPENGL_RENDERER
     { "nIsBackBufferPreserved", "()Z",         (void*) android_view_GLES20Canvas_isBackBufferPreserved },
     { "nPreserveBackBuffer",    "()Z",         (void*) android_view_GLES20Canvas_preserveBackBuffer },
+    { "nDisableVsync",          "()V",         (void*) android_view_GLES20Canvas_disableVsync },
 
     { "nCreateRenderer",    "()I",             (void*) android_view_GLES20Canvas_createRenderer },
     { "nDestroyRenderer",   "(I)V",            (void*) android_view_GLES20Canvas_destroyRenderer },
diff --git a/docs/html/images/opengl/coordinates.png b/docs/html/images/opengl/coordinates.png
deleted file mode 100644
index 7180cd5..0000000
--- a/docs/html/images/opengl/coordinates.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/opengl/helloopengl-es10-1.png b/docs/html/images/opengl/helloopengl-es10-1.png
deleted file mode 100644
index bdfbcdb..0000000
--- a/docs/html/images/opengl/helloopengl-es10-1.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/opengl/helloopengl-es10-2.png b/docs/html/images/opengl/helloopengl-es10-2.png
deleted file mode 100644
index c07dabb..0000000
--- a/docs/html/images/opengl/helloopengl-es10-2.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/opengl/helloopengl-es20-1.png b/docs/html/images/opengl/helloopengl-es20-1.png
deleted file mode 100644
index 44abe77..0000000
--- a/docs/html/images/opengl/helloopengl-es20-1.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/opengl/helloopengl-es20-2.png b/docs/html/images/opengl/helloopengl-es20-2.png
deleted file mode 100644
index 22fa52c..0000000
--- a/docs/html/images/opengl/helloopengl-es20-2.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 06a046d..0fc10bf 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -782,26 +782,6 @@
     }
   },
   {
-    tags: ['tutorial', 'gl', 'new'],
-    path: 'tutorials/opengl/opengl-es10.html',
-    title: {
-      en: 'Hello OpenGL ES 1.0'
-    },
-    description: {
-      en: 'The basics of implementing an application using the OpenGL ES 1.0 APIs.'
-    }
-  },
-  {
-    tags: ['tutorial', 'gl', 'new'],
-    path: 'tutorials/opengl/opengl-es20.html',
-    title: {
-      en: 'Hello OpenGL ES 2.0'
-    },
-    description: {
-      en: 'The basics of implementing an application using the OpenGL ES 2.0 APIs.'
-    }
-  },
-  {
     tags: ['tutorial', 'testing'],
     path: 'tutorials/testing/helloandroid_test.html',
     title: {
diff --git a/docs/html/resources/tutorials/opengl/opengl-es10.jd b/docs/html/resources/tutorials/opengl/opengl-es10.jd
deleted file mode 100644
index d18a547..0000000
--- a/docs/html/resources/tutorials/opengl/opengl-es10.jd
+++ /dev/null
@@ -1,409 +0,0 @@
-page.title=Hello OpenGL ES 1.0
-parent.title=Tutorials
-parent.link=../../browser.html?tag=tutorial
-@jd:body
-
-
-<div id="qv-wrapper">
-  <div id="qv">
-    <h2>In this document</h2>
-    
-    <ol>
-      <li><a href="#creating">Creating an OpenGL ES 1.0 Application</a></li>
-      <li>
-        <a href="#drawing">Drawing Graphic Elements</a>
-        <ol>
-          <li><a href="#define-triangle">Defining a Triangle</a></li>
-          <li><a href="#draw-triangle">Draw the Triangle</a></li>
-        </ol>
-      </li>
-      <li><a href="#projection-and-views">Using Projection and Views</a></li>
-      <li><a href="#motion">Adding Motion</a></li>
-      <li><a href="#resources">Additional Resources</a></li>
-      
-    </ol>
-    <h2 id="code-samples-list">Related Samples</h2>
-    <ol>
-      <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
-index.html">API Demos - graphics</a></li>
-      <li><a
-        href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
-GLSurfaceViewActivity.html">GLSurfaceViewActivity</a></li>
-    </ol>
-    <h2>See also</h2>
-    <ol>
-      <li><a href="{@docRoot}guide/topics/graphics/opengl.html">3D with OpenGL</a></li>
-      <li><a href="{@docRoot}resources/tutorials/opengl/opengl-es20.html">Hello OpenGL
-ES 2.0</a></li>
-    </ol>
-    </div>
-  </div>
-
-<p>This tutorial shows you how to create a simple Android application that uses OpenGL ES 1.0 and
-perform some basic operations using the OpenGL ES 1.0 API, including:</p>
-
-<ul>
-  <li>Creating an application using {@link android.opengl.GLSurfaceView} and {@link
-android.opengl.GLSurfaceView.Renderer}</li>
-  <li>Defining a graphic object and drawing it</li>
-  <li>Defining and applying an projection and view</li>
-  <li>Applying rotation to the drawn object</li>
-</ul>
-
-<p>This tutorial demonstrates use of the OpenGL ES 1.0 API. Both the OpenGL ES 1.0 and the ES 1.1
-API are supported by the Android framework since release 1.0 (API Level 1). The OpenGL ES 1.1 API
-is an extention of the 1.0 API, and it's capabilities are beyond the scope of this tutorial.</p>
-
-<p>Beginning with Android 2.2 (API Level 8), the framework supports OpenGL ES 2.0. For more
-information about compatibility for OpenGL versions and Android devices, see the <a
-href="{@docRoot}guide/topics/graphics/opengl.html#compatibility">3D with OpenGL</a> document.</p>
-
-
-<h2 id="creating">Creating an OpenGL ES 1.0 Application</h2>
-
-<p>OpenGL applications for Android have the same basic structure as other applications, however
-OpenGL applications use {@link android.opengl.GLSurfaceView} where other, non-OpenGL
-applications use the {@link android.view.View} or {@link android.view.SurfaceView} class.<p>
- 
-<p>To get started using OpenGL in your Android application, you must implement both a {@link
-android.opengl.GLSurfaceView} and a {@link android.opengl.GLSurfaceView.Renderer}. The {@link
-android.opengl.GLSurfaceView} is the main view type for the OpenGL applications and the {@link
-android.opengl.GLSurfaceView.Renderer} controls what is drawn within that view. For more
-information about these classes, see the <a href="{@docRoot}guide/topics/graphics/opengl.html">3D
-with OpenGL</a> document.</p>
-
-<p>To create an application that uses OpenGL ES 1.0:</p>
-  
-<ol>
-  <li>Start a new Android project with an Activity called <code>HelloOpenGLES10</code>. 
-    
-    <p class="note"><b>Note:</b> If you have not created a basic Android application yet, follow the
-      <a href="{@docRoot}resources/tutorials/hello-world.html">Hello World Tutorial</a> instructions
-      to familiarize yourself with the process.</p>
-  </li>
-  
-  <li>Modify the <code>HelloOpenGLES10</code> class as follows:
-<pre>
-package com.example.android.apis.graphics;
-
-import android.app.Activity;
-import android.content.Context;
-import android.opengl.GLSurfaceView;
-import android.os.Bundle;
-
-public class HelloOpenGLES10 extends Activity {
-  
-    private GLSurfaceView mGLView;    
-  
-    &#64;Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        
-        mGLView = new HelloOpenGLSurfaceView(this);
-        setContentView(mGLView);
-    }
-    
-    &#64;Override
-    protected void onPause() {
-        super.onPause();
-        mGLView.onPause();
-    }
-    
-    &#64;Override
-    protected void onResume() {
-        super.onResume();
-        mGLView.onResume();
-    }
-    
-}
-  
-class HelloOpenGLES10SurfaceView extends GLSurfaceView {
-
-    public HelloOpenGLES10SurfaceView(Context context){
-        super(context);
-        setRenderer(new HelloOpenGLES10Renderer());
-    }
-
-}
-</pre>
-    <p>This Activity class creates a basic container for a {@link android.opengl.GLSurfaceView}.</p>
-  </li>
-
-  <li>Create the following class <code>HelloOpenGLES10Renderer</code>, which implements the 
-    {@link android.opengl.GLSurfaceView.Renderer} interface:
-
-<pre>
-package com.example.android.apis.graphics;
-
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-
-import android.opengl.GLSurfaceView;
-
-public class HelloOpenGLES10Renderer implements GLSurfaceView.Renderer {
-
-    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
-        // Set the background frame color
-        gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
-    }
-    
-    public void onDrawFrame(GL10 gl) {
-        // Redraw background color
-        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-    }
-    
-    public void onSurfaceChanged(GL10 gl, int width, int height) {
-        gl.glViewport(0, 0, width, height);
-    }
-  
-}
-</pre>
-  </li>
-</ol>
-
-<p>These classes create a simple Android application which displays a grey screen using OpenGL
-ES 1.0 calls. While this application does not do anything very interesting, by creating these two
-classes, you have layed the foundation needed to start drawing graphic elements with OpenGL ES
-1.0.</p>
-
-<p>If you are familiar with the OpenGL ES APIs, these two classes should give you enough information
-to start using the OpenGL ES 1.0 API and creating graphics. However, if you need a bit more help
-getting started with OpenGL, head on to the next sections for a few more tips.</p>
-
-<h2 id="drawing">Drawing Graphic Elements</h2>
-
-<p>Once you have implemented a {@link android.opengl.GLSurfaceView.Renderer}, the next step is to
-draw something on it. This section shows you how to define and draw a basic triangle shape with the
-Android OpenGL ES 1.0 API.</p>
-
-<p class="note"><b>Note:</b> The following instructions build on the previous section, so if you
-have not been following along, go back to the <a href="#get-started">previous section</a> and catch
-up.</p>
-
-<h3 id="define-triangle">Defining a Triangle</h3>
-
-<p>OpenGL allows you to define objects using coordinates in three-dimensional space. So, before you
-  can draw a triangle, you must define its coordinates. In OpenGL, the typical way to do this is to
-  define a vertex array for the coordinates.</p>
-  
-<p>By default, OpenGL ES assumes a coordinate system where 0,0,0 (X,Y,Z) specifies the center of
-  the {@link android.opengl.GLSurfaceView} frame, 1,1,0 is the top right corner of the frame  and 
--1,-1,0 is  bottom left corner of the frame.</p> 
-
-<p>To define a vertex array for a triangle:</p>
-
-<ol>
-  <li>In your <code>HelloOpenGLES10Renderer</code> class, add new member variable to contain the
-vertices of a triangle shape:
-<pre>
-    private FloatBuffer triangleVB;
-</pre>
-  </li>
-
-  <li>Create a method, <code>initShapes()</code> which populates this member variable:
-<pre>
-    private void initShapes(){
-    
-        float triangleCoords[] = {
-            // X, Y, Z
-            -0.5f, -0.25f, 0,
-             0.5f, -0.25f, 0,
-             0.0f,  0.559016994f, 0
-        }; 
-        
-        // initialize vertex Buffer for triangle  
-        ByteBuffer vbb = ByteBuffer.allocateDirect(
-                // (# of coordinate values * 4 bytes per float)
-                triangleCoords.length * 4); 
-        vbb.order(ByteOrder.nativeOrder());
-        triangleVB = vbb.asFloatBuffer();
-        triangleVB.put(triangleCoords);
-        triangleVB.position(0);
-    
-    }
-</pre>
-    <p>This method defines a two-dimensional triangle shape with three equal sides.</p>
-  </li>
-  <li>Modify your <code>onSurfaceCreated()</code> method to initialize your triangle: 
-    <pre>
-    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
-    
-        // Set the background frame color
-        gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
-        
-        // initialize the triangle vertex array
-        initShapes();
-    }
-</pre>
-  <p class="warning"><strong>Warning:</strong> Shapes and other static objects should be initialized
-    once in your <code>onSurfaceCreated()</code> method for best performance. Avoid initializing the
-    new objects in <code>onDrawFrame()</code>, as this causes the system to re-create the objects
-    for every frame redraw and slows down your application.
-  </p>
-  </li>
-
-</ol>
-
-<h3 id="draw-triangle">Draw the Triangle</h3>
-
-<p>Now that you have defined a shape to draw, you can use the OpenGL APIs to draw the
-object.</p>
-
-<p>To draw the triangle with OpenGL:</p>
-  
-<ol>
-  <li>Before you can draw your triangle, you must tell OpenGL that you are using vertex arrays.
-    Modify your <code>onSurfaceCreated()</code> method to enable vertex arrays.
-<pre>
-    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
-    
-        // Set the background frame color
-        gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
-        
-        // initialize the triangle vertex array
-        initShapes();
-        
-        // Enable use of vertex arrays
-        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
-    }
-</pre>
-    <p>At this point, you are ready to draw the triangle object in the OpenGL frame.</p>
-  </li>
-  
-  <li>Modify your <code>onDrawFrame()</code> method to draw the triangle.
-<pre>
-    public void onDrawFrame(GL10 gl) {
-        // Redraw background color
-        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-    
-        // Draw the triangle
-        gl.glColor4f(0.63671875f, 0.76953125f, 0.22265625f, 0.0f);
-        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triangleVB);
-        gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
-    }
-</pre>
-    <p><b>Note:</b> Since the triangle is stationary at this point, the system is redrawing the
-      object repeatedly in exactly the same place and so is not the most efficient use of the OpenGL
-      graphics pipeline. In a <a href="#motion">later section</a>, we add motion to the object to
-      justify this use of processing power.</p>
-  </li>
-</ol>
-
-<p id="squashed-triangle">Try running this example application on your emulator or test device and
-you should see something like this:</p>
-
-<img src="{@docRoot}images/opengl/helloopengl-es10-1.png">
-
-<p>There are a few problems with this example. First of all, it's not going to impress your
-friends. Secondly, the triangle is a bit squashed and changes shape when you change the screen
-orientation of the test device. The reason the shape is skewed is due to the fact that the object is
-being rendered in a frame which is not perfectly square. We fix that problem in the
-<a href="#projection-and-views">next section</a>.</p>
-
-<h2 id="projection-and-views">Using Projection and Views</h2>
-
-<p>OpenGL Projection and Views provide a way to calculate the coordinates of graphic objects in
-realistic proportions on graphics displays of any size. One of the basic problems in displaying
-graphics is that Android device displays are typically not square and&#8212;by default&#8212;OpenGL
-happily maps a perfectly square, uniform coordinate system onto your typically non-square
-screen.</p>
-
-<img src="{@docRoot}images/opengl/coordinates.png">
-
-<p>The illustration above shows the uniform coordinate system assumed for an OpenGL frame on the
-  left, and how these coordinates actually map to a typical device screen in landscape orientation
-  on the right. To solve this problem, you can apply OpenGL projection modes and views to transform
-  object coordinates so your graphic objects have the correct proportions on any display.</p>
-
-<p>To use a projection transformation on your triangle:</p>
-<ol>
-  <li>Modify your <code>onSurfaceChanged()</code> method to enable {@link
-    javax.microedition.khronos.opengles.GL10#GL_PROJECTION GL10.GL_PROJECTION} mode, calculate the
-    screen ratio and apply the ratio as a transformation of the object coordinates.
-<pre>
-  public void onSurfaceChanged(GL10 gl, int width, int height) {
-      gl.glViewport(0, 0, width, height);
-      
-      // make adjustments for screen ratio
-      float ratio = (float) width / height;
-      gl.glMatrixMode(GL10.GL_PROJECTION);
-      gl.glLoadIdentity();
-      gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);
-  }  
-</pre>
-  </li>
-
-  <li>Next, modify your <code>onDrawFrame()</code> method to apply the {@link
-javax.microedition.khronos.opengles.GL10#GL_MODELVIEW GL_MODELVIEW} mode and set
-a view point for the display using {@link
-android.opengl.GLU#gluLookAt(javax.microedition.khronos.opengles.GL10, float, float, float, float,
-float, float, float, float, float) GLU#gluLookAt()}.
-<pre>
-    public void onDrawFrame(GL10 gl) {
-        // Redraw background color
-        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-        
-        // Set GL_MODELVIEW transformation mode
-        gl.glMatrixMode(GL10.GL_MODELVIEW);
-        gl.glLoadIdentity();
-        
-        // When using GL_MODELVIEW, you must set the view point
-        GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);        
-        
-        // Draw the triangle
-        ...
-    }
-</pre>
-  </li>
-</ol>
-
-<p>Try running this updated application on your emulator or test device and you should see something
-like this:</p>
-
-<img src="{@docRoot}images/opengl/helloopengl-es10-2.png">
-
-<p>Now that you have applied this transformation, the triangle has three equal sides, instead of the
-squashed display in the <a href="#squashed-triangle">earlier version</a>.</p>
-
-<h2 id="motion">Adding Motion</h2>
-
-<p>While it may be interesting exercise to create static graphic objects with OpenGL ES, chances
-are you want at least some of your objects to move. In this section, we add motion to to our
-triangle by rotating it.</p>
-
-<p>To add rotation to your triangle:</p>
-<ul>
-  <li>Modify your <code>onDrawFrame()</code> method to rotate the triangle object:
-<pre>
-    public void onDrawFrame(GL10 gl) {
-        ...    
-        // When using GL_MODELVIEW, you must set the view point
-        GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);        
-    
-        // Create a rotation for the triangle
-        long time = SystemClock.uptimeMillis() % 4000L;
-        float angle = 0.090f * ((int) time);
-        gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);        
-        
-        // Draw the triangle
-        ...
-    }
-</pre>
-  </li>
-</ul>
-
-<p>Run the application with this code and your triangle should rotate around its center.</p>
-
-<!--
-  <h2>TouchScreen Interaction</h2>
-  Optional extra (using code from API examples)
-  -->
-
-<h2 id="resources">Additional Resources</h2>
-
-<p>Be sure to check out the OpenGL ES code samples are available in the
-<a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/index.html">API
-Demos</a> sample application and listed in <a href="#code-samples-list">Related Samples</a>
-sidebar above.
-</p>
diff --git a/docs/html/resources/tutorials/opengl/opengl-es20.jd b/docs/html/resources/tutorials/opengl/opengl-es20.jd
deleted file mode 100644
index 5cdc343..0000000
--- a/docs/html/resources/tutorials/opengl/opengl-es20.jd
+++ /dev/null
@@ -1,514 +0,0 @@
-page.title=Hello OpenGL ES 1.0
-parent.title=Tutorials
-parent.link=../../browser.html?tag=tutorial
-@jd:body
-
-
-<div id="qv-wrapper">
-  <div id="qv">
-    <h2>In this document</h2>
-    
-    <ol>
-      <li><a href="#creating">Creating an OpenGL ES 2.0 Application</a></li>
-      <li>
-        <a href="#drawing">Drawing Graphic Elements</a>
-        <ol>
-          <li><a href="#define-triangle">Defining a Triangle</a></li>
-          <li><a href="#draw-triangle">Draw the Triangle</a></li>
-        </ol>
-      </li>
-      <li><a href="#projection-and-views">Using Projection and Views</a></li>
-      <li><a href="#motion">Adding Motion</a></li>
-      <li><a href="#resources">Additional Resources</a></li>
-      
-    </ol>
-    <h2 id="code-samples-list">Related Samples</h2>
-    <ol>
-      <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
-index.html">API Demos - graphics</a></li>
-      <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
-GLES20Activity.html">OpenGL ES 2.0 Example</a></li>
-    </ol>
-    <h2>See also</h2>
-    <ol>
-      <li><a href="{@docRoot}guide/topics/graphics/opengl.html">3D with OpenGL</a></li>
-      <li><a href="{@docRoot}resources/tutorials/opengl/opengl-es10.html">Hello OpenGL
-ES 1.0</a></li>
-    </ol>
-    </div>
-  </div>
-
-<p>This tutorial shows you how to create a simple Android application that uses OpenGL ES 2.0 and
-perform some basic operations using the OpenGL ES 2.0 API, including:</p>
-
-<ul>
-  <li>Creating an application using {@link android.opengl.GLSurfaceView} and {@link
-android.opengl.GLSurfaceView.Renderer}</li>
-  <li>Defining a graphic object and drawing it</li>
-  <li>Defining and applying an projection and view</li>
-  <li>Applying rotation to the drawn object</li>
-</ul>
-
-<p>This tutorial demonstrates use of the OpenGL ES 2.0 API. Beginning with Android 2.2 (API Level
-8), the framework supports OpenGL ES 2.0.</p>
-
-<p>Both the OpenGL ES 1.0 and the ES 1.1 API are supported by the Android framework since release
-1.0 (API Level 1).For more information about compatibility for OpenGL versions and Android devices,
-see the <a href="{@docRoot}guide/topics/graphics/opengl.html#compatibility">3D with OpenGL</a>
-document.</p>
-
-
-<h2 id="creating">Creating an OpenGL ES 1.0 Application</h2>
-
-<p>OpenGL applications for Android have the same basic structure as other applications, however
-OpenGL applications use {@link android.opengl.GLSurfaceView} where other, non-OpenGL
-applications use the {@link android.view.View} or {@link android.view.SurfaceView} class.<p>
- 
-<p>To get started using OpenGL in your Android application, you must implement both a {@link
-android.opengl.GLSurfaceView} and a {@link android.opengl.GLSurfaceView.Renderer}. The {@link
-android.opengl.GLSurfaceView} is the main view type for the OpenGL applications and the {@link
-android.opengl.GLSurfaceView.Renderer} controls what is drawn within that view. For more
-information about these classes, see the <a href="{@docRoot}guide/topics/graphics/opengl.html">3D
-with OpenGL</a> document.</p>
-
-<p>To create an application that uses OpenGL ES 2.0:</p>
-  
-<ol>
-  <li>Start a new Android project with an Activity called <code>HelloOpenGLES20</code>. 
-    
-    <p class="note"><b>Note:</b> If you have not created a basic Android application yet, follow the
-      <a href="{@docRoot}resources/tutorials/hello-world.html">Hello World Tutorial</a> instructions
-      to familiarize yourself with the process.</p>
-  </li>
-  
-  <li>Modify the <code>HelloOpenGLES20</code> class as follows:
-<pre>
-package com.example.android.apis.graphics;
-
-import android.app.Activity;
-import android.content.Context;
-import android.opengl.GLSurfaceView;
-import android.os.Bundle;
-
-public class HelloOpenGLES20 extends Activity {
-  
-    private GLSurfaceView mGLView;    
-  
-    &#64;Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        
-        mGLView = new HelloOpenGLES20SurfaceView(this);
-        setContentView(mGLView);
-    }
-    
-    &#64;Override
-    protected void onPause() {
-        super.onPause();
-        mGLView.onPause();
-    }
-    
-    &#64;Override
-    protected void onResume() {
-        super.onResume();
-        mGLView.onResume();
-    }
-}
-  
-class HelloOpenGLES20SurfaceView extends GLSurfaceView {
-
-    public HelloOpenGLES20SurfaceView(Context context){
-        super(context);
-        
-        // Create an OpenGL ES 2.0 context.
-        setEGLContextClientVersion(2);
-
-        setRenderer(new HelloOpenGLES20Renderer());
-    }
-}
-</pre>
-    <p>This Activity class creates a basic container for a {@link android.opengl.GLSurfaceView}.</p>
-  </li>
-
-  <li>Create the following class <code>HelloOpenGLES20Renderer</code>, which implements the 
-    {@link android.opengl.GLSurfaceView.Renderer} interface:
-
-<pre>
-package com.example.android.apis.graphics;
-
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-
-import android.opengl.GLES20;
-import android.opengl.GLSurfaceView;
-
-public class HelloOpenGLES20Renderer implements GLSurfaceView.Renderer {
-  
-    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
-    
-        // Set the background frame color
-        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
-    }
-    
-    public void onDrawFrame(GL10 unused) {
-    
-        // Redraw background color
-        GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-    }
-    
-    public void onSurfaceChanged(GL10 unused, int width, int height) {
-        GLES20.glViewport(0, 0, width, height);
-    }
-  
-}
-</pre>
-  </li>
-</ol>
-
-<p>These classes create a simple Android application which displays a grey screen using OpenGL
-ES 2.0 calls. While this application does not do anything very interesting, by creating these two
-classes, you have layed the foundation needed to start drawing graphic elements with OpenGL ES
-2.0.</p>
-
-<p>If your application only supports OpenGL ES 2.0, then you should declare that your application
-  requires OpenGL ES 2.0 by adding the following settings to your <a                       
-href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a></code> file as
-shown below.</p>
-
-<pre>
-...
-    &lt;/application&gt;
-    
-    &lt;!-- Tell the system that you need ES 2.0. --&gt;
-    &lt;uses-feature android:glEsVersion="0x00020000" android:required="true" /&gt;
-
-&lt;/manifest&gt;
-</pre>
-
-<p>Adding this declaration hides your application from devices that do not support OpenGL ES 2.0
-in the Android Market.</p>
-  
-<p>If you are familiar with the OpenGL ES APIs, these preceding classes and the AndroidManifest.xml
-declaration should give you enough information to start using the OpenGL ES API and creating
-graphics. However, if you need a bit more help getting started with OpenGL, head on to the next
-sections for a few more tips.</p>
-
-
-<h2 id="drawing">Drawing Graphic Elements</h2>
-
-<p>Once you have implemented a {@link android.opengl.GLSurfaceView.Renderer}, the next step is to
-draw something on it. This section shows you how to define and draw a basic triangle shape with the
-OpenGL ES 2.0 API.</p>
-
-<p class="note"><b>Note:</b> The following instructions build on the previous section, so if you
-have not been following along, go back to the <a href="#get-started">previous section</a> and catch
-up.</p>
-
-<h3 id="define-triangle">Defining a Triangle</h3>
-
-<p>OpenGL allows you to define objects using coordinates in three-dimensional space. So, before you
-  can draw a triangle, you must define its coordinates. In OpenGL, the typical way to do this is to
-  define a vertex array for the coordinates.</p>
-  
-<p>By default, OpenGL ES assumes a coordinate system where 0,0,0 (X,Y,Z) specifies the center of
-  the {@link android.opengl.GLSurfaceView} frame, 1,1,0 is the top right corner of the frame  and 
--1,-1,0 is  bottom left corner of the frame.</p> 
-
-<p>To define a vertex array for a triangle:</p>
-
-<ol>
-  <li>In your <code>HelloOpenGLES20Renderer</code> class, add new member variable to contain the
-vertices of a triangle shape:
-<pre>
-    private FloatBuffer triangleVB;
-</pre>
-  </li>
-
-  <li>Create a method, <code>initShapes()</code> which populates this member variable:
-<pre>
-    private void initShapes(){
-    
-        float triangleCoords[] = {
-            // X, Y, Z
-            -0.5f, -0.25f, 0,
-             0.5f, -0.25f, 0,
-             0.0f,  0.559016994f, 0
-        }; 
-        
-        // initialize vertex Buffer for triangle  
-        ByteBuffer vbb = ByteBuffer.allocateDirect(
-                // (# of coordinate values * 4 bytes per float)
-                triangleCoords.length * 4); 
-        vbb.order(ByteOrder.nativeOrder());
-        triangleVB = vbb.asFloatBuffer();
-        triangleVB.put(triangleCoords);
-        triangleVB.position(0);
-    
-    }
-</pre>
-    <p>This method defines a two-dimensional triangle shape with three equal sides.</p>
-  </li>
-  <li>Modify your <code>onSurfaceCreated()</code> method to initialize your triangle:
-<pre>
-    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
-    
-        // Set the background frame color
-        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
-        
-        // initialize the triangle vertex array
-        initShapes();
-    }
-</pre>
-  <p class="warning"><strong>Warning:</strong> Shapes and other static objects should be initialized
-    once in your <code>onSurfaceCreated()</code> method for best performance. Avoid initializing the
-    new objects in <code>onDrawFrame()</code>, as this causes the system to re-create the objects
-    for every frame redraw and slows down your application.
-  </p>
-  </li>
-
-</ol>
-
-<h3 id="draw-triangle">Draw the Triangle</h3>
-
-<p>Now that you have defined a shape to draw, you can now use the OpenGL APIs to draw the
-  object. In order to do this with OpenGL ES 2.0, you must define a vertex shader and a
-fragment shader to describe how to draw your shape.</p>
-
-<p>To draw the triangle with OpenGL:</p>
-  
-<ol>
-  <li>In your <code>HelloOpenGLES20Renderer</code> class, define a vertex shader and a fragment
-shader.
-<pre>
-    private final String vertexShaderCode = 
-        "attribute vec4 vPosition;    \n" +
-        "void main(){         \n" +
-        " gl_Position = vPosition;  \n" +
-        "}                \n";
-    
-    private final String fragmentShaderCode = 
-        "precision mediump float; \n" +
-        "void main(){       \n" +
-        " gl_FragColor = vec4 (0.63671875, 0.76953125, 0.22265625, 1.0); \n" +
-        "} \n";
-</pre>
-  </li>
-  <li>In your <code>HelloOpenGLES20Renderer</code> class, create a method for loading the shaders.
-<pre>
-    private int loadShader(int type, String shaderCode){
-    
-        int shader = GLES20.glCreateShader(type);
-        
-        GLES20.glShaderSource(shader, shaderCode);
-        GLES20.glCompileShader(shader);
-        
-        return shader;
-    }
-</pre>
-  </li>
-  
-  <li>Add the following members to your <code>HelloOpenGLES20Renderer</code> class for an OpenGL
-Program.
-<pre>
-    private int mProgram;
-    private int maPositionHandle;
-</pre>
-  </li>
-  
-  <li>Modify your <code>onSurfaceCreated()</code> method to load the shaders and attach them to a
-OpenGL Program.
-<pre>
-    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
-    
-        // Set the background frame color
-        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
-        
-        // initialize the triangle vertex array
-        initShapes();
-        
-        // Create shaders for shape and attach to program
-        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
-        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
-        
-        mProgram = GLES20.glCreateProgram();
-        GLES20.glAttachShader(mProgram, vertexShader);
-        GLES20.glAttachShader(mProgram, fragmentShader);
-        GLES20.glLinkProgram(mProgram);
-        
-        maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
-    }
-</pre>
-    <p>At this point, you are ready to draw the triangle object in the OpenGL frame.</p>
-  </li>
-  
-  <li>Modify your <code>onDrawFrame()</code> method to draw the triangle.
-<pre>
-    public void onDrawFrame(GL10 unused) {
-        
-        // Redraw background color
-        GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-    
-        // Specify a program with shaders
-        GLES20.glUseProgram(mProgram);
-        
-        // Prepare the triangle data
-        GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 12, triangleVB);
-        GLES20.glEnableVertexAttribArray(maPositionHandle);
-        
-        // Draw the triangle
-        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
-    }
-</pre>
-    <p><b>Note:</b> Since the triangle is stationary at this point, the system is redrawing the
-      object repeatedly in exactly the same place and so is not the most efficient use of the OpenGL
-      graphics pipeline. In a <a href="#motion">later section</a>, we add motion to the object to
-      justify this use of processing power.</p>
-  </li>
-</ol>
-
-<p id="squashed-triangle">Try running this example application on your emulator or test device and
-you should see something like this:</p>
-
-<img src="{@docRoot}images/opengl/helloopengl-es20-1.png">
-
-<p>There are a few problems with this example. First of all, it's not going to impress your
-friends. Secondly, the triangle is a bit squashed and changes shape when you change the screen
-orientation of the test device. The reason the shape is skewed is due to the fact that the object is
-being rendered in a frame which is not perfectly square. We fix that problem in the
-<a href="#projection-and-views">next section</a>.</p>
-
-<h2 id="projection-and-views">Using Projection and Views</h2>
-
-<p>OpenGL Projection and Views provide a way to calculate the coordinates of graphic objects in
-realistic proportions on graphics displays of any size. One of the basic problems in displaying
-graphics is that Android device displays are typically not square and&#8212;by default&#8212;OpenGL
-happily maps a perfectly square, uniform coordinate system onto your typically non-square
-screen.</p>
-
-<img src="{@docRoot}images/opengl/coordinates.png">
-  
-<p>The illustration above shows the uniform coordinate system assumed for an OpenGL frame on the
-  left, and how these coordinates actually map to a typical device screen in landscape orientation
-  on the right. To solve this problem, you can apply OpenGL projection modes and views to transform
-  object coordinates so your graphic objects have the correct proportions on any display.</p>
-
-<p>To use a projection transformation on your triangle:</p>
-<ol>
-  <li>Add the following members to your <code>HelloOpenGLES20Renderer</code> class.
-<pre>
-    private int muMVPMatrixHandle;
-    private float[] mMVPMatrix = new float[16];
-    private float[] mMMatrix = new float[16];
-    private float[] mVMatrix = new float[16];
-    private float[] mProjMatrix = new float[16];
-</pre>
-    </li>
-    <li>Modify your <code>vertexShaderCode</code> string to add a variable for a model view
-projection matrix.
-<pre>
-    private final String vertexShaderCode = 
-        "uniform mat4 uMVPMatrix;   \n" +
-        "attribute vec4 vPosition;  \n" +
-        "void main(){               \n" +
-        " gl_Position = uMVPMatrix * vPosition; \n" +
-        "}  \n";
-</pre>
-    </li>
-    <li>Modify your <code>onSurfaceChanged()</code> method to reference the <code>uMVPMatrix</code>
-shader variable you added and define a view transformation matrix.
-<pre>
-    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
-        ...
-        maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
-        
-        muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
-        Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
-    }
-</pre>
-    </li>
-    <li>Next, modify your <code>onSurfaceChanged()</code> method to calculate the device screen
-ration and create a projection matrix.
-<pre>
-    public void onSurfaceChanged(GL10 unused, int width, int height) {
-        GLES20.glViewport(0, 0, width, height);
-        
-        float ratio = (float) width / height;
-        Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
-    }  
-</pre>
-    </li>
-    <li>Finally, modify your <code>onDrawFrame()</code> method to apply the transformation.
-<pre>
-    public void onDrawFrame(GL10 unused) {
-        ...
-        // Apply a ModelView Projection transformation
-        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
-        GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
-        
-        // Draw the triangle
-        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);        
-    }
-</pre>
-    </li>
-  </ol>
-  
-<p>Try running this updated application on your emulator or test device and you should see
-something like this:</p>
-  
-  <img src="{@docRoot}images/opengl/helloopengl-es20-2.png">
-    
-<p>Now that you have applied this transformation, the triangle has three equal sides, instead of the
-squashed display in the <a href="#squashed-triangle">earlier version</a>.</p>
-
-
-<h2 id="motion">Adding Motion</h2>
-
-<p>While it may be interesting exercise to create static graphic objects with OpenGL ES, chances
-are you want at least some of your objects to move. In this section, we add motion to to our
-triangle by rotating it.</p>
-
-<p>To add rotation to your triangle:</p>
-<ol>
-  <li>Add an additional tranformation matrix member to your <code>HelloOpenGLES20Renderer</code>
-class.
-    <pre>
-      private float[] mMMatrix = new float[16];
-    </pre>
-    </li>  <li>Modify your <code>onDrawFrame()</code> method to rotate the triangle object:
-<pre>
-    public void onDrawFrame(GL10 gl) {
-        ...
-    
-        // Create a rotation for the triangle
-        long time = SystemClock.uptimeMillis() % 4000L;
-        float angle = 0.090f * ((int) time);
-        Matrix.setRotateM(mMMatrix, 0, angle, 0, 0, 1.0f);
-        Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
-        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
-        
-        // Apply a ModelView Projection transformation
-        //Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
-        GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
-        
-        // Draw the triangle
-        ...
-    }
-</pre>
-  </li>
-</ol>
-
-<p>Run the application with this code and your triangle should rotate around its center.</p>
-
-<!--
-  <h2>TouchScreen Interaction</h2>
-  Optional extra (using code from API examples)
-  -->
-
-<h2 id="resources">Additional Resources</h2>
-
-<p>Be sure to check out the OpenGL ES code samples are available in the
-<a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/index.html">API
-Demos</a> sample application and listed in <a href="#code-samples-list">Related Samples</a>
-sidebar above.
-</p>
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index e900584..6254192 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -67,6 +67,22 @@
     Type mType;
     Bitmap mBitmap;
     int mUsage;
+    Allocation mAdaptedAllocation;
+
+    boolean mConstrainedLOD;
+    boolean mConstrainedFace;
+    boolean mConstrainedY;
+    boolean mConstrainedZ;
+    int mSelectedY;
+    int mSelectedZ;
+    int mSelectedLOD;
+    Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
+
+    int mCurrentDimX;
+    int mCurrentDimY;
+    int mCurrentDimZ;
+    int mCurrentCount;
+
 
     /**
      * The usage of the allocation.  These signal to renderscript
@@ -139,6 +155,19 @@
         }
     }
 
+    private void updateCacheInfo(Type t) {
+        mCurrentDimX = t.getX();
+        mCurrentDimY = t.getY();
+        mCurrentDimZ = t.getZ();
+        mCurrentCount = mCurrentDimX;
+        if (mCurrentDimY > 1) {
+            mCurrentCount *= mCurrentDimY;
+        }
+        if (mCurrentDimZ > 1) {
+            mCurrentCount *= mCurrentDimZ;
+        }
+    }
+
     Allocation(int id, RenderScript rs, Type t, int usage) {
         super(id, rs);
         if ((usage & ~(USAGE_SCRIPT |
@@ -149,6 +178,10 @@
             throw new RSIllegalArgumentException("Unknown usage specified.");
         }
         mType = t;
+
+        if (t != null) {
+            updateCacheInfo(t);
+        }
     }
 
     private void validateIsInt32() {
@@ -210,6 +243,7 @@
         if(typeID != 0) {
             mType = new Type(typeID, mRS);
             mType.updateFromNative();
+            updateCacheInfo(mType);
         }
     }
 
@@ -234,15 +268,15 @@
     public void copyFrom(BaseObj[] d) {
         mRS.validate();
         validateIsObject();
-        if (d.length != mType.getCount()) {
+        if (d.length != mCurrentCount) {
             throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
-                                                 mType.getCount() + ", array length = " + d.length);
+                                                 mCurrentCount + ", array length = " + d.length);
         }
         int i[] = new int[d.length];
         for (int ct=0; ct < d.length; ct++) {
             i[ct] = d[ct].getID();
         }
-        copy1DRangeFromUnchecked(0, mType.getCount(), i);
+        copy1DRangeFromUnchecked(0, mCurrentCount, i);
     }
 
     private void validateBitmapFormat(Bitmap b) {
@@ -292,8 +326,7 @@
     }
 
     private void validateBitmapSize(Bitmap b) {
-        if(mType.getX() != b.getWidth() ||
-           mType.getY() != b.getHeight()) {
+        if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
             throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
         }
     }
@@ -307,7 +340,7 @@
      */
     public void copyFromUnchecked(int[] d) {
         mRS.validate();
-        copy1DRangeFromUnchecked(0, mType.getCount(), d);
+        copy1DRangeFromUnchecked(0, mCurrentCount, d);
     }
     /**
      * Copy an allocation from an array.  This variant is not type
@@ -318,7 +351,7 @@
      */
     public void copyFromUnchecked(short[] d) {
         mRS.validate();
-        copy1DRangeFromUnchecked(0, mType.getCount(), d);
+        copy1DRangeFromUnchecked(0, mCurrentCount, d);
     }
     /**
      * Copy an allocation from an array.  This variant is not type
@@ -329,7 +362,7 @@
      */
     public void copyFromUnchecked(byte[] d) {
         mRS.validate();
-        copy1DRangeFromUnchecked(0, mType.getCount(), d);
+        copy1DRangeFromUnchecked(0, mCurrentCount, d);
     }
     /**
      * Copy an allocation from an array.  This variant is not type
@@ -340,7 +373,7 @@
      */
     public void copyFromUnchecked(float[] d) {
         mRS.validate();
-        copy1DRangeFromUnchecked(0, mType.getCount(), d);
+        copy1DRangeFromUnchecked(0, mCurrentCount, d);
     }
 
     /**
@@ -352,7 +385,7 @@
      */
     public void copyFrom(int[] d) {
         mRS.validate();
-        copy1DRangeFrom(0, mType.getCount(), d);
+        copy1DRangeFrom(0, mCurrentCount, d);
     }
 
     /**
@@ -364,7 +397,7 @@
      */
     public void copyFrom(short[] d) {
         mRS.validate();
-        copy1DRangeFrom(0, mType.getCount(), d);
+        copy1DRangeFrom(0, mCurrentCount, d);
     }
 
     /**
@@ -376,7 +409,7 @@
      */
     public void copyFrom(byte[] d) {
         mRS.validate();
-        copy1DRangeFrom(0, mType.getCount(), d);
+        copy1DRangeFrom(0, mCurrentCount, d);
     }
 
     /**
@@ -388,7 +421,7 @@
      */
     public void copyFrom(float[] d) {
         mRS.validate();
-        copy1DRangeFrom(0, mType.getCount(), d);
+        copy1DRangeFrom(0, mCurrentCount, d);
     }
 
     /**
@@ -420,8 +453,7 @@
             throw new RSIllegalArgumentException("Field packer length " + data.length +
                                                " not divisible by element size " + eSize + ".");
         }
-        data1DChecks(xoff, count, data.length, data.length);
-        mRS.nAllocationData1D(getID(), xoff, 0, count, data, data.length);
+        copy1DRangeFromUnchecked(xoff, count, data);
     }
 
     /**
@@ -448,7 +480,8 @@
                                                " does not match component size " + eSize + ".");
         }
 
-        mRS.nAllocationElementData1D(getID(), xoff, 0, component_number, data, data.length);
+        mRS.nAllocationElementData1D(getID(), xoff, mSelectedLOD,
+                                     component_number, data, data.length);
     }
 
     private void data1DChecks(int off, int count, int len, int dataSize) {
@@ -459,11 +492,11 @@
         if(count < 1) {
             throw new RSIllegalArgumentException("Count must be >= 1.");
         }
-        if((off + count) > mType.getCount()) {
-            throw new RSIllegalArgumentException("Overflow, Available count " + mType.getCount() +
+        if((off + count) > mCurrentCount) {
+            throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
                                                ", got " + count + " at offset " + off + ".");
         }
-        if((len) < dataSize) {
+        if(len < dataSize) {
             throw new RSIllegalArgumentException("Array too small for allocation type.");
         }
     }
@@ -494,7 +527,7 @@
     public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
         int dataSize = mType.mElement.getSizeBytes() * count;
         data1DChecks(off, count, d.length * 4, dataSize);
-        mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
+        mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize);
     }
     /**
      * Copy part of an allocation from an array.  This variant is
@@ -508,7 +541,7 @@
     public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
         int dataSize = mType.mElement.getSizeBytes() * count;
         data1DChecks(off, count, d.length * 2, dataSize);
-        mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
+        mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize);
     }
     /**
      * Copy part of an allocation from an array.  This variant is
@@ -522,7 +555,7 @@
     public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
         int dataSize = mType.mElement.getSizeBytes() * count;
         data1DChecks(off, count, d.length, dataSize);
-        mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
+        mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize);
     }
     /**
      * Copy part of an allocation from an array.  This variant is
@@ -536,7 +569,7 @@
     public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
         int dataSize = mType.mElement.getSizeBytes() * count;
         data1DChecks(off, count, d.length * 4, dataSize);
-        mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
+        mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize);
     }
 
     /**
@@ -606,21 +639,25 @@
      */
     public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
         mRS.nAllocationData2D(getID(), off, 0,
-                              0, Type.CubemapFace.POSITIVE_X.mID,
+                              mSelectedLOD, mSelectedFace.mID,
                               count, 1, data.getID(), dataOff, 0,
-                              0, Type.CubemapFace.POSITIVE_X.mID);
+                              data.mSelectedLOD, data.mSelectedFace.mID);
     }
 
     private void validate2DRange(int xoff, int yoff, int w, int h) {
-        if (xoff < 0 || yoff < 0) {
-            throw new RSIllegalArgumentException("Offset cannot be negative.");
-        }
-        if (h < 0 || w < 0) {
-            throw new RSIllegalArgumentException("Height or width cannot be negative.");
-        }
-        if ((xoff + w) > mType.mDimX ||
-            (yoff + h) > mType.mDimY) {
-            throw new RSIllegalArgumentException("Updated region larger than allocation.");
+        if (mAdaptedAllocation != null) {
+
+        } else {
+
+            if (xoff < 0 || yoff < 0) {
+                throw new RSIllegalArgumentException("Offset cannot be negative.");
+            }
+            if (h < 0 || w < 0) {
+                throw new RSIllegalArgumentException("Height or width cannot be negative.");
+            }
+            if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
+                throw new RSIllegalArgumentException("Updated region larger than allocation.");
+            }
         }
     }
 
@@ -637,25 +674,29 @@
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
-        mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length);
+        mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
+                              w, h, data, data.length);
     }
 
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
-        mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 2);
+        mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
+                              w, h, data, data.length * 2);
     }
 
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
-        mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 4);
+        mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
+                              w, h, data, data.length * 4);
     }
 
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
-        mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 4);
+        mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
+                              w, h, data, data.length * 4);
     }
 
     /**
@@ -675,9 +716,9 @@
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
         mRS.nAllocationData2D(getID(), xoff, yoff,
-                              0, Type.CubemapFace.POSITIVE_X.mID,
+                              mSelectedLOD, mSelectedFace.mID,
                               w, h, data.getID(), dataXoff, dataYoff,
-                              0, Type.CubemapFace.POSITIVE_X.mID);
+                              data.mSelectedLOD, data.mSelectedFace.mID);
     }
 
     /**
@@ -693,7 +734,7 @@
         mRS.validate();
         validateBitmapFormat(data);
         validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
-        mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, data);
+        mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
     }
 
 
@@ -750,6 +791,7 @@
         int typeID = mRS.nAllocationGetType(getID());
         mType = new Type(typeID, mRS);
         mType.updateFromNative();
+        updateCacheInfo(mType);
     }
 
     /*
diff --git a/graphics/java/android/renderscript/AllocationAdapter.java b/graphics/java/android/renderscript/AllocationAdapter.java
index 77dd86a..ca5246a 100644
--- a/graphics/java/android/renderscript/AllocationAdapter.java
+++ b/graphics/java/android/renderscript/AllocationAdapter.java
@@ -17,228 +17,92 @@
 package android.renderscript;
 
 import android.content.res.Resources;
-import android.content.res.AssetManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.util.Log;
 import android.util.TypedValue;
 
 /**
  *
  **/
 public class AllocationAdapter extends Allocation {
-    private boolean mConstrainedLOD;
-    private boolean mConstrainedFace;
-    private boolean mConstrainedY;
-    private boolean mConstrainedZ;
-
-    private int mSelectedDimX;
-    private int mSelectedDimY;
-    private int mSelectedDimZ;
-    private int mSelectedCount;
-    private Allocation mAlloc;
-
-    private int mSelectedLOD = 0;
-    private Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
-
     AllocationAdapter(int id, RenderScript rs, Allocation alloc) {
-        super(id, rs, null, alloc.mUsage);
-        mAlloc = alloc;
+        super(id, rs, alloc.mType, alloc.mUsage);
+        mAdaptedAllocation = alloc;
     }
 
-
     int getID() {
-        return mAlloc.getID();
+        return mAdaptedAllocation.getID();
     }
 
-    public void copyFrom(BaseObj[] d) {
-        mRS.validate();
-        if (d.length != mSelectedCount) {
-            throw new RSIllegalArgumentException("Array size mismatch, allocation size = " +
-                                                 mSelectedCount + ", array length = " + d.length);
-        }
-        int i[] = new int[d.length];
-        for (int ct=0; ct < d.length; ct++) {
-            i[ct] = d[ct].getID();
-        }
-        subData1D(0, mAlloc.mType.getCount(), i);
-    }
-
-    void validateBitmap(Bitmap b) {
-        mRS.validate();
-        if(mSelectedDimX != b.getWidth() ||
-           mSelectedDimY != b.getHeight()) {
-            throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
-        }
-    }
-
-    public void copyFrom(int[] d) {
-        mRS.validate();
-        subData1D(0, mSelectedCount, d);
-    }
-    public void copyFrom(short[] d) {
-        mRS.validate();
-        subData1D(0, mSelectedCount, d);
-    }
-    public void copyFrom(byte[] d) {
-        mRS.validate();
-        subData1D(0, mSelectedCount, d);
-    }
-    public void copyFrom(float[] d) {
-        mRS.validate();
-        subData1D(0, mSelectedCount, d);
-    }
-    public void copyFrom(Bitmap b) {
-        validateBitmap(b);
-        mRS.nAllocationCopyFromBitmap(getID(), b);
-    }
-
-    public void copyTo(Bitmap b) {
-        validateBitmap(b);
-        mRS.nAllocationCopyToBitmap(getID(), b);
-    }
-
-
+    /**
+     * @hide
+     */
     public void subData(int xoff, FieldPacker fp) {
-        int eSize = mAlloc.mType.mElement.getSizeBytes();
-        final byte[] data = fp.getData();
-
-        int count = data.length / eSize;
-        if ((eSize * count) != data.length) {
-            throw new RSIllegalArgumentException("Field packer length " + data.length +
-                                               " not divisible by element size " + eSize + ".");
-        }
-        data1DChecks(xoff, count, data.length, data.length);
-        mRS.nAllocationData1D(getID(), xoff, mSelectedLOD, count, data, data.length);
+        super.setFromFieldPacker(xoff, fp);
     }
-
-
+    /**
+     * @hide
+     */
     public void subElementData(int xoff, int component_number, FieldPacker fp) {
-        if (component_number >= mAlloc.mType.mElement.mElements.length) {
-            throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
-        }
-        if(xoff < 0) {
-            throw new RSIllegalArgumentException("Offset must be >= 0.");
-        }
-
-        final byte[] data = fp.getData();
-        int eSize = mAlloc.mType.mElement.mElements[component_number].getSizeBytes();
-
-        if (data.length != eSize) {
-            throw new RSIllegalArgumentException("Field packer sizelength " + data.length +
-                                               " does not match component size " + eSize + ".");
-        }
-
-        mRS.nAllocationElementData1D(getID(), xoff, mSelectedLOD, component_number, data, data.length);
+        super.setFromFieldPacker(xoff, component_number, fp);
     }
-
-    void data1DChecks(int off, int count, int len, int dataSize) {
-        mRS.validate();
-        if(off < 0) {
-            throw new RSIllegalArgumentException("Offset must be >= 0.");
-        }
-        if(count < 1) {
-            throw new RSIllegalArgumentException("Count must be >= 1.");
-        }
-        if((off + count) > mSelectedCount) {
-            throw new RSIllegalArgumentException("Overflow, Available count " + mAlloc.mType.getCount() +
-                                               ", got " + count + " at offset " + off + ".");
-        }
-        if((len) < dataSize) {
-            throw new RSIllegalArgumentException("Array too small for allocation type.  len = " +
-                                                 len + ", dataSize = " + dataSize);
-        }
-    }
-
+    /**
+     * @hide
+     */
     public void subData1D(int off, int count, int[] d) {
-        int dataSize = mAlloc.mType.mElement.getSizeBytes() * count;
-        data1DChecks(off, count, d.length * 4, dataSize);
-        mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize);
+        super.copy1DRangeFrom(off, count, d);
     }
+    /**
+     * @hide
+     */
     public void subData1D(int off, int count, short[] d) {
-        int dataSize = mAlloc.mType.mElement.getSizeBytes() * count;
-        data1DChecks(off, count, d.length * 2, dataSize);
-        mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize);
+        super.copy1DRangeFrom(off, count, d);
     }
+    /**
+     * @hide
+     */
     public void subData1D(int off, int count, byte[] d) {
-        int dataSize = mAlloc.mType.mElement.getSizeBytes() * count;
-        data1DChecks(off, count, d.length, dataSize);
-        mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize);
+        super.copy1DRangeFrom(off, count, d);
     }
+    /**
+     * @hide
+     */
     public void subData1D(int off, int count, float[] d) {
-        int dataSize = mAlloc.mType.mElement.getSizeBytes() * count;
-        data1DChecks(off, count, d.length * 4, dataSize);
-        mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize);
+        super.copy1DRangeFrom(off, count, d);
     }
-
     /**
-     * Copy part of an allocation from another allocation.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param data the source data allocation.
-     * @param dataOff off The offset of the first element in data to
-     *          be copied.
+     * @hide
      */
-    public void subData1D(int off, int count, AllocationAdapter data, int dataOff) {
-        mRS.nAllocationData2D(getID(), off, 0,
-                              mSelectedLOD, mSelectedFace.mID,
-                              count, 1, data.getID(), dataOff, 0,
-                              data.mSelectedLOD, data.mSelectedFace.mID);
-    }
-
-
     public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
-        mRS.validate();
-        mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
-                              w, h, d, d.length * 4);
+        super.copy2DRangeFrom(xoff, yoff, w, h, d);
     }
-
-    public void subData2D(int xoff, int yoff, int w, int h, float[] d) {
-        mRS.validate();
-        mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
-                              w, h, d, d.length * 4);
-    }
-
     /**
-     * Copy a rectangular region into the allocation from another
-     * allocation.
-     *
-     * @param xoff X offset of the region to update.
-     * @param yoff Y offset of the region to update.
-     * @param w Width of the incoming region to update.
-     * @param h Height of the incoming region to update.
-     * @param data source allocation.
-     * @param dataXoff X offset in data of the region to update.
-     * @param dataYoff Y offset in data of the region to update.
+     * @hide
      */
-    public void subData2D(int xoff, int yoff, int w, int h,
-                          AllocationAdapter data, int dataXoff, int dataYoff) {
-        mRS.validate();
-        mRS.nAllocationData2D(getID(), xoff, yoff,
-                              mSelectedLOD, mSelectedFace.mID,
-                              w, h, data.getID(), dataXoff, dataYoff,
-                              data.mSelectedLOD, data.mSelectedFace.mID);
+    public void subData2D(int xoff, int yoff, int w, int h, float[] d) {
+        super.copy2DRangeFrom(xoff, yoff, w, h, d);
     }
-
+    /**
+     * @hide
+     */
     public void readData(int[] d) {
-        mRS.validate();
-        mRS.nAllocationRead(getID(), d);
+        super.copyTo(d);
     }
-
+    /**
+     * @hide
+     */
     public void readData(float[] d) {
-        mRS.validate();
-        mRS.nAllocationRead(getID(), d);
+        super.copyTo(d);
     }
 
-    private void initLOD(int lod) {
+    void initLOD(int lod) {
         if (lod < 0) {
             throw new RSIllegalArgumentException("Attempting to set negative lod (" + lod + ").");
         }
 
-        int tx = mAlloc.mType.getX();
-        int ty = mAlloc.mType.getY();
-        int tz = mAlloc.mType.getZ();
+        int tx = mAdaptedAllocation.mType.getX();
+        int ty = mAdaptedAllocation.mType.getY();
+        int tz = mAdaptedAllocation.mType.getZ();
 
         for (int ct=0; ct < lod; ct++) {
             if ((tx==1) && (ty == 1) && (tz == 1)) {
@@ -250,25 +114,31 @@
             if (tz > 1) tz >>= 1;
         }
 
-        mSelectedDimX = tx;
-        mSelectedDimY = ty;
-        mSelectedCount = tx;
-        if (ty > 1) {
-            mSelectedCount *= ty;
+        mCurrentDimX = tx;
+        mCurrentDimY = ty;
+        mCurrentDimZ = tz;
+        mCurrentCount = mCurrentDimX;
+        if (mCurrentDimY > 1) {
+            mCurrentCount *= mCurrentDimY;
         }
-        if (tz > 1) {
-            mSelectedCount *= tz;
+        if (mCurrentDimZ > 1) {
+            mCurrentCount *= mCurrentDimZ;
         }
+        mSelectedY = 0;
+        mSelectedZ = 0;
     }
 
     /**
      * Set the active LOD.  The LOD must be within the range for the
-     * type being adapted.
+     * type being adapted.  The base allocation must have mipmaps.
+     *
+     * Because this changes the dimensions of the adapter the
+     * current Y and Z will be reset.
      *
      * @param lod The LOD to make active.
      */
     public void setLOD(int lod) {
-        if (!mAlloc.getType().hasMipmaps()) {
+        if (!mAdaptedAllocation.getType().hasMipmaps()) {
             throw new RSInvalidStateException("Cannot set LOD when the allocation type does not include mipmaps.");
         }
         if (!mConstrainedLOD) {
@@ -278,22 +148,81 @@
         initLOD(lod);
     }
 
+    /**
+     * Set the active Face.  The base allocation must be of a type
+     * that includes faces.
+     *
+     * @param cf The face to make active.
+     */
     public void setFace(Type.CubemapFace cf) {
+        if (!mAdaptedAllocation.getType().hasFaces()) {
+            throw new RSInvalidStateException("Cannot set Face when the allocation type does not include faces.");
+        }
+        if (!mConstrainedFace) {
+            throw new RSInvalidStateException("Cannot set LOD when the adapter includes mipmaps.");
+        }
+        if (cf == null) {
+            throw new RSIllegalArgumentException("Cannot set null face.");
+        }
+
         mSelectedFace = cf;
     }
 
+    /**
+     * Set the active Y.  The y value must be within the range for
+     * the allocation being adapted.  The base allocation must
+     * contain the Y dimension.
+     *
+     * @param y The y to make active.
+     */
     public void setY(int y) {
-        mSelectedDimY = y;
+        if (mAdaptedAllocation.getType().getY() == 0) {
+            throw new RSInvalidStateException("Cannot set Y when the allocation type does not include Y dim.");
+        }
+        if (mAdaptedAllocation.getType().getY() <= y) {
+            throw new RSInvalidStateException("Cannot set Y greater than dimension of allocation.");
+        }
+        if (!mConstrainedY) {
+            throw new RSInvalidStateException("Cannot set Y when the adapter includes Y.");
+        }
+
+        mSelectedY = y;
     }
 
+    /**
+     * Set the active Z.  The z value must be within the range for
+     * the allocation being adapted.  The base allocation must
+     * contain the Z dimension.
+     *
+     * @param z The z to make active.
+     */
     public void setZ(int z) {
+        if (mAdaptedAllocation.getType().getZ() == 0) {
+            throw new RSInvalidStateException("Cannot set Z when the allocation type does not include Z dim.");
+        }
+        if (mAdaptedAllocation.getType().getZ() <= z) {
+            throw new RSInvalidStateException("Cannot set Z greater than dimension of allocation.");
+        }
+        if (!mConstrainedZ) {
+            throw new RSInvalidStateException("Cannot set Z when the adapter includes Z.");
+        }
+
+        mSelectedZ = z;
     }
 
-    // creation
-    //static public AllocationAdapter create1D(RenderScript rs, Allocation a) {
-    //}
+    static public AllocationAdapter create1D(RenderScript rs, Allocation a) {
+        rs.validate();
+        AllocationAdapter aa = new AllocationAdapter(0, rs, a);
+        aa.mConstrainedLOD = true;
+        aa.mConstrainedFace = true;
+        aa.mConstrainedY = true;
+        aa.mConstrainedZ = true;
+        aa.initLOD(0);
+        return aa;
+    }
 
     static public AllocationAdapter create2D(RenderScript rs, Allocation a) {
+        android.util.Log.e("rs", "create2d " + a);
         rs.validate();
         AllocationAdapter aa = new AllocationAdapter(0, rs, a);
         aa.mConstrainedLOD = true;
@@ -305,6 +234,16 @@
     }
 
 
+    /**
+     * Override the Allocation resize.  Resizing adapters is not
+     * allowed and will throw a RSInvalidStateException.
+     *
+     * @param dimX ignored.
+     */
+    public synchronized void resize(int dimX) {
+        throw new RSInvalidStateException("Resize not allowed for Adapters.");
+    }
+
 }
 
 
diff --git a/include/media/EffectBassBoostApi.h b/include/media/EffectBassBoostApi.h
deleted file mode 100644
index 56119eb..0000000
--- a/include/media/EffectBassBoostApi.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_EFFECTBASSBOOSTAPI_H_
-#define ANDROID_EFFECTBASSBOOSTAPI_H_
-
-#include <hardware/audio_effect.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-#ifndef OPENSL_ES_H_
-static const effect_uuid_t SL_IID_BASSBOOST_ = { 0x0634f220, 0xddd4, 0x11db, 0xa0fc, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_BASSBOOST = &SL_IID_BASSBOOST_;
-#endif //OPENSL_ES_H_
-
-/* enumerated parameter settings for BassBoost effect */
-typedef enum
-{
-    BASSBOOST_PARAM_STRENGTH_SUPPORTED,
-    BASSBOOST_PARAM_STRENGTH
-} t_bassboost_params;
-
-#if __cplusplus
-}  // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTBASSBOOSTAPI_H_*/
diff --git a/include/media/EffectEnvironmentalReverbApi.h b/include/media/EffectEnvironmentalReverbApi.h
deleted file mode 100644
index f11c5ec..0000000
--- a/include/media/EffectEnvironmentalReverbApi.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_EFFECTENVIRONMENTALREVERBAPI_H_
-#define ANDROID_EFFECTENVIRONMENTALREVERBAPI_H_
-
-#include <hardware/audio_effect.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-#ifndef OPENSL_ES_H_
-static const effect_uuid_t SL_IID_ENVIRONMENTALREVERB_ = { 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x6, 0x83, 0x9e } };
-const effect_uuid_t * const SL_IID_ENVIRONMENTALREVERB = &SL_IID_ENVIRONMENTALREVERB_;
-#endif //OPENSL_ES_H_
-
-/* enumerated parameter settings for environmental reverb effect */
-typedef enum
-{
-    // Parameters below are as defined in OpenSL ES specification for environmental reverb interface
-    REVERB_PARAM_ROOM_LEVEL,            // in millibels,    range -6000 to 0
-    REVERB_PARAM_ROOM_HF_LEVEL,         // in millibels,    range -4000 to 0
-    REVERB_PARAM_DECAY_TIME,            // in milliseconds, range 100 to 20000
-    REVERB_PARAM_DECAY_HF_RATIO,        // in permilles,    range 100 to 1000
-    REVERB_PARAM_REFLECTIONS_LEVEL,     // in millibels,    range -6000 to 0
-    REVERB_PARAM_REFLECTIONS_DELAY,     // in milliseconds, range 0 to 65
-    REVERB_PARAM_REVERB_LEVEL,          // in millibels,    range -6000 to 0
-    REVERB_PARAM_REVERB_DELAY,          // in milliseconds, range 0 to 65
-    REVERB_PARAM_DIFFUSION,             // in permilles,    range 0 to 1000
-    REVERB_PARAM_DENSITY,               // in permilles,    range 0 to 1000
-    REVERB_PARAM_PROPERTIES,
-    REVERB_PARAM_BYPASS
-} t_env_reverb_params;
-
-//t_reverb_settings is equal to SLEnvironmentalReverbSettings defined in OpenSL ES specification.
-typedef struct s_reverb_settings {
-    int16_t     roomLevel;
-    int16_t     roomHFLevel;
-    uint32_t    decayTime;
-    int16_t     decayHFRatio;
-    int16_t     reflectionsLevel;
-    uint32_t    reflectionsDelay;
-    int16_t     reverbLevel;
-    uint32_t    reverbDelay;
-    int16_t     diffusion;
-    int16_t     density;
-} __attribute__((packed)) t_reverb_settings;
-
-
-#if __cplusplus
-}  // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTENVIRONMENTALREVERBAPI_H_*/
diff --git a/include/media/EffectEqualizerApi.h b/include/media/EffectEqualizerApi.h
deleted file mode 100644
index 950d138..0000000
--- a/include/media/EffectEqualizerApi.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_EFFECTEQUALIZERAPI_H_
-#define ANDROID_EFFECTEQUALIZERAPI_H_
-
-#include <hardware/audio_effect.h>
-
-#ifndef OPENSL_ES_H_
-static const effect_uuid_t SL_IID_EQUALIZER_ = { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_EQUALIZER = &SL_IID_EQUALIZER_;
-#endif //OPENSL_ES_H_
-
-#if __cplusplus
-extern "C" {
-#endif
-
-/* enumerated parameters for Equalizer effect */
-typedef enum
-{
-    EQ_PARAM_NUM_BANDS,             // Gets the number of frequency bands that the equalizer supports.
-    EQ_PARAM_LEVEL_RANGE,           // Returns the minimum and maximum band levels supported.
-    EQ_PARAM_BAND_LEVEL,            // Gets/Sets the gain set for the given equalizer band.
-    EQ_PARAM_CENTER_FREQ,           // Gets the center frequency of the given band.
-    EQ_PARAM_BAND_FREQ_RANGE,       // Gets the frequency range of the given frequency band.
-    EQ_PARAM_GET_BAND,              // Gets the band that has the most effect on the given frequency.
-    EQ_PARAM_CUR_PRESET,            // Gets/Sets the current preset.
-    EQ_PARAM_GET_NUM_OF_PRESETS,    // Gets the total number of presets the equalizer supports.
-    EQ_PARAM_GET_PRESET_NAME,       // Gets the preset name based on the index.
-    EQ_PARAM_PROPERTIES             // Gets/Sets all parameters at a time.
-} t_equalizer_params;
-
-//t_equalizer_settings groups all current equalizer setting for backup and restore.
-typedef struct s_equalizer_settings {
-    uint16_t curPreset;
-    uint16_t numBands;
-    uint16_t bandLevels[];
-} t_equalizer_settings;
-
-#if __cplusplus
-}  // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTEQUALIZERAPI_H_*/
diff --git a/include/media/EffectPresetReverbApi.h b/include/media/EffectPresetReverbApi.h
deleted file mode 100644
index e5b168a6..0000000
--- a/include/media/EffectPresetReverbApi.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_EFFECTPRESETREVERBAPI_H_
-#define ANDROID_EFFECTPRESETREVERBAPI_H_
-
-#include <hardware/audio_effect.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-#ifndef OPENSL_ES_H_
-static const effect_uuid_t SL_IID_PRESETREVERB_ = { 0x47382d60, 0xddd8, 0x11db, 0xbf3a, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_PRESETREVERB = &SL_IID_PRESETREVERB_;
-#endif //OPENSL_ES_H_
-
-/* enumerated parameter settings for preset reverb effect */
-typedef enum
-{
-    REVERB_PARAM_PRESET
-} t_preset_reverb_params;
-
-
-typedef enum
-{
-    REVERB_PRESET_NONE,
-    REVERB_PRESET_SMALLROOM,
-    REVERB_PRESET_MEDIUMROOM,
-    REVERB_PRESET_LARGEROOM,
-    REVERB_PRESET_MEDIUMHALL,
-    REVERB_PRESET_LARGEHALL,
-    REVERB_PRESET_PLATE,
-    REVERB_PRESET_LAST = REVERB_PRESET_PLATE
-} t_reverb_presets;
-
-#if __cplusplus
-}  // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTPRESETREVERBAPI_H_*/
diff --git a/include/media/EffectVirtualizerApi.h b/include/media/EffectVirtualizerApi.h
deleted file mode 100644
index 2e216e2..0000000
--- a/include/media/EffectVirtualizerApi.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_EFFECTVIRTUALIZERAPI_H_
-#define ANDROID_EFFECTVIRTUALIZERAPI_H_
-
-#include <hardware/audio_effect.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-#ifndef OPENSL_ES_H_
-static const effect_uuid_t SL_IID_VIRTUALIZER_ = { 0x37cc2c00, 0xdddd, 0x11db, 0x8577, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_VIRTUALIZER = &SL_IID_VIRTUALIZER_;
-#endif //OPENSL_ES_H_
-
-/* enumerated parameter settings for virtualizer effect */
-typedef enum
-{
-    VIRTUALIZER_PARAM_STRENGTH_SUPPORTED,
-    VIRTUALIZER_PARAM_STRENGTH
-} t_virtualizer_params;
-
-#if __cplusplus
-}  // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTVIRTUALIZERAPI_H_*/
diff --git a/include/media/EffectVisualizerApi.h b/include/media/EffectVisualizerApi.h
deleted file mode 100644
index e0fa328..0000000
--- a/include/media/EffectVisualizerApi.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_EFFECTVISUALIZERAPI_H_
-#define ANDROID_EFFECTVISUALIZERAPI_H_
-
-#include <hardware/audio_effect.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-#ifndef OPENSL_ES_H_
-static const effect_uuid_t SL_IID_VISUALIZATION_ =
-    { 0xe46b26a0, 0xdddd, 0x11db, 0x8afd, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_VISUALIZATION = &SL_IID_VISUALIZATION_;
-#endif //OPENSL_ES_H_
-
-#define VISUALIZER_CAPTURE_SIZE_MAX 1024  // maximum capture size in samples
-#define VISUALIZER_CAPTURE_SIZE_MIN 128   // minimum capture size in samples
-
-/* enumerated parameters for Visualizer effect */
-typedef enum
-{
-    VISU_PARAM_CAPTURE_SIZE,        // Sets the number PCM samples in the capture.
-} t_visualizer_params;
-
-/* commands */
-typedef enum
-{
-    VISU_CMD_CAPTURE = EFFECT_CMD_FIRST_PROPRIETARY, // Gets the latest PCM capture.
-}t_visualizer_cmds;
-
-// VISU_CMD_CAPTURE retrieves the latest PCM snapshot captured by the visualizer engine.
-// It returns the number of samples specified by VISU_PARAM_CAPTURE_SIZE
-// in 8 bit unsigned format (0 = 0x80)
-
-#if __cplusplus
-}  // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTVISUALIZERAPI_H_*/
diff --git a/include/media/Visualizer.h b/include/media/Visualizer.h
index b8746c2..5d2c874 100644
--- a/include/media/Visualizer.h
+++ b/include/media/Visualizer.h
@@ -18,7 +18,7 @@
 #define ANDROID_MEDIA_VISUALIZER_H
 
 #include <media/AudioEffect.h>
-#include <media/EffectVisualizerApi.h>
+#include <audio_effects/effect_visualizer.h>
 #include <string.h>
 
 /**
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index c06400e..88433fb 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -1180,8 +1180,7 @@
     sp<FrameCondition> mFC;
 };
 
-// XXX: This test is disabled because it causes hangs on some devices.
-TEST_F(SurfaceTextureGLToGLTest, DISABLED_UpdateTexImageBeforeFrameFinishedWorks) {
+TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageBeforeFrameFinishedWorks) {
     class PT : public ProducerThread {
         virtual void render() {
             glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
@@ -1199,8 +1198,7 @@
     // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
 }
 
-// XXX: This test is disabled because it causes hangs on some devices.
-TEST_F(SurfaceTextureGLToGLTest, DISABLED_UpdateTexImageAfterFrameFinishedWorks) {
+TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageAfterFrameFinishedWorks) {
     class PT : public ProducerThread {
         virtual void render() {
             glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
@@ -1218,8 +1216,7 @@
     // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
 }
 
-// XXX: This test is disabled because it causes hangs on some devices.
-TEST_F(SurfaceTextureGLToGLTest, DISABLED_RepeatedUpdateTexImageBeforeFrameFinishedWorks) {
+TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageBeforeFrameFinishedWorks) {
     enum { NUM_ITERATIONS = 1024 };
 
     class PT : public ProducerThread {
@@ -1247,8 +1244,7 @@
     }
 }
 
-// XXX: This test is disabled because it causes hangs on some devices.
-TEST_F(SurfaceTextureGLToGLTest, DISABLED_RepeatedUpdateTexImageAfterFrameFinishedWorks) {
+TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageAfterFrameFinishedWorks) {
     enum { NUM_ITERATIONS = 1024 };
 
     class PT : public ProducerThread {
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 0310bc3..3c2d80d 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -27,6 +27,7 @@
 
 #include "Rect.h"
 #include "SkiaColorFilter.h"
+#include "Texture.h"
 #include "Vertex.h"
 
 namespace android {
@@ -40,14 +41,18 @@
  * A layer has dimensions and is backed by an OpenGL texture or FBO.
  */
 struct Layer {
-    Layer(const uint32_t layerWidth, const uint32_t layerHeight):
-            width(layerWidth), height(layerHeight) {
+    Layer(const uint32_t layerWidth, const uint32_t layerHeight) {
         mesh = NULL;
         meshIndices = NULL;
         meshElementCount = 0;
-        isCacheable = true;
-        isTextureLayer = false;
+        cacheable = true;
+        textureLayer = false;
         renderTarget = GL_TEXTURE_2D;
+        texture.width = layerWidth;
+        texture.height = layerHeight;
+        colorFilter = NULL;
+        firstFilter = true;
+        firstWrap = true;
     }
 
     ~Layer() {
@@ -64,12 +69,152 @@
         regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
                bounds.rightBottom().x, bounds.rightBottom().y);
 
-        const float texX = 1.0f / float(width);
-        const float texY = 1.0f / float(height);
+        const float texX = 1.0f / float(texture.width);
+        const float texY = 1.0f / float(texture.height);
         const float height = layer.getHeight();
         texCoords.set(
                regionRect.left * texX, (height - regionRect.top) * texY,
                regionRect.right * texX, (height - regionRect.bottom) * texY);
+
+        regionRect.translate(layer.left, layer.top);
+    }
+
+    inline uint32_t getWidth() {
+        return texture.width;
+    }
+
+    inline uint32_t getHeight() {
+        return texture.height;
+    }
+
+    void setSize(uint32_t width, uint32_t height) {
+        texture.width = width;
+        texture.height = height;
+    }
+
+    inline void setBlend(bool blend) {
+        texture.blend = blend;
+    }
+
+    inline bool isBlend() {
+        return texture.blend;
+    }
+
+    inline void setAlpha(int alpha) {
+        this->alpha = alpha;
+    }
+
+    inline void setAlpha(int alpha, SkXfermode::Mode mode) {
+        this->alpha = alpha;
+        this->mode = mode;
+    }
+
+    inline int getAlpha() {
+        return alpha;
+    }
+
+    inline SkXfermode::Mode getMode() {
+        return mode;
+    }
+
+    inline void setEmpty(bool empty) {
+        this->empty = empty;
+    }
+
+    inline bool isEmpty() {
+        return empty;
+    }
+
+    inline void setFbo(GLuint fbo) {
+        this->fbo = fbo;
+    }
+
+    inline GLuint getFbo() {
+        return fbo;
+    }
+
+    inline GLuint* getTexturePointer() {
+        return &texture.id;
+    }
+
+    inline GLuint getTexture() {
+        return texture.id;
+    }
+
+    inline GLenum getRenderTarget() {
+        return renderTarget;
+    }
+
+    inline void setRenderTarget(GLenum renderTarget) {
+        this->renderTarget = renderTarget;
+    }
+
+    void setWrap(GLenum wrapS, GLenum wrapT, bool bindTexture = false, bool force = false) {
+        if (firstWrap || force || wrapS != texture.wrapS || wrapT != texture.wrapT) {
+            firstWrap = true;
+            texture.setWrap(wrapS, wrapT);
+            if (bindTexture) {
+                glBindTexture(renderTarget, texture.id);
+            }
+            glTexParameteri(renderTarget, GL_TEXTURE_WRAP_S, wrapS);
+            glTexParameteri(renderTarget, GL_TEXTURE_WRAP_T, wrapT);
+        }
+    }
+
+    void setFilter(GLenum min, GLenum mag, bool bindTexture = false, bool force = false) {
+        if (firstFilter || force || min != texture.minFilter || mag != texture.magFilter) {
+            firstFilter = false;
+            texture.setFilter(min, mag);
+            if (bindTexture) {
+                glBindTexture(renderTarget, texture.id);
+            }
+            glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min);
+            glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag);
+        }
+    }
+
+    inline bool isCacheable() {
+        return cacheable;
+    }
+
+    inline void setCacheable(bool cacheable) {
+        this->cacheable = cacheable;
+    }
+
+    inline bool isTextureLayer() {
+        return textureLayer;
+    }
+
+    inline void setTextureLayer(bool textureLayer) {
+        this->textureLayer = textureLayer;
+    }
+
+    inline SkiaColorFilter* getColorFilter() {
+        return colorFilter;
+    }
+
+    inline void setColorFilter(SkiaColorFilter* filter) {
+        colorFilter = filter;
+    }
+
+    inline void bindTexture() {
+        glBindTexture(renderTarget, texture.id);
+    }
+
+    inline void generateTexture() {
+        glGenTextures(1, &texture.id);
+    }
+
+    inline void deleteTexture() {
+        if (texture.id) glDeleteTextures(1, &texture.id);
+    }
+
+    inline void allocateTexture(GLenum format, GLenum storage) {
+        glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0, format, storage, NULL);
+    }
+
+    inline mat4& getTexTransform() {
+        return texTransform;
     }
 
     /**
@@ -82,43 +227,6 @@
     Rect texCoords;
 
     /**
-     * Name of the FBO used to render the layer. If the name is 0
-     * this layer is not backed by an FBO, but a simple texture.
-     */
-    GLuint fbo;
-
-    /**
-     * Opacity of the layer.
-     */
-    int alpha;
-    /**
-     * Blending mode of the layer.
-     */
-    SkXfermode::Mode mode;
-    /**
-     * Indicates whether this layer should be blended.
-     */
-    bool blend;
-
-    /**
-     * Indicates whether this layer has been used already.
-     */
-    bool empty;
-
-    /**
-     * Name of the texture used to render the layer.
-     */
-    GLuint texture;
-    /**
-     * Width of the layer texture.
-     */
-    uint32_t width;
-    /**
-     * Height of the layer texture.
-     */
-    uint32_t height;
-
-    /**
      * Dirty region indicating what parts of the layer
      * have been drawn.
      */
@@ -130,37 +238,66 @@
     Rect regionRect;
 
     /**
-     * Color filter used to draw this layer. Optional.
-     */
-    SkiaColorFilter* colorFilter;
-
-    /**
      * If the layer can be rendered as a mesh, this is non-null.
      */
     TextureVertex* mesh;
     uint16_t* meshIndices;
     GLsizei meshElementCount;
 
+private:
+    /**
+     * Name of the FBO used to render the layer. If the name is 0
+     * this layer is not backed by an FBO, but a simple texture.
+     */
+    GLuint fbo;
+
+    /**
+     * Indicates whether this layer has been used already.
+     */
+    bool empty;
+
+    /**
+     * The texture backing this layer.
+     */
+    Texture texture;
+
     /**
      * If set to true (by default), the layer can be reused.
      */
-    bool isCacheable;
+    bool cacheable;
 
     /**
      * When set to true, this layer must be treated as a texture
      * layer.
      */
-    bool isTextureLayer;
+    bool textureLayer;
+
+    /**
+     * Indicates the render target.
+     */
+    GLenum renderTarget;
+
+    /**
+     * Color filter used to draw this layer. Optional.
+     */
+    SkiaColorFilter* colorFilter;
+
+    /**
+     * Opacity of the layer.
+     */
+    int alpha;
+    /**
+     * Blending mode of the layer.
+     */
+    SkXfermode::Mode mode;
 
     /**
      * Optional texture coordinates transform.
      */
     mat4 texTransform;
 
-    /**
-     * Indicates the render target.
-     */
-    GLenum renderTarget;
+    bool firstFilter;
+    bool firstWrap;
 }; // struct Layer
 
 }; // namespace uirenderer
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index b2d795f..1a15e87 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -68,8 +68,8 @@
 
 void LayerCache::deleteLayer(Layer* layer) {
     if (layer) {
-        mSize -= layer->width * layer->height * 4;
-        glDeleteTextures(1, &layer->texture);
+        mSize -= layer->getWidth() * layer->getHeight() * 4;
+        layer->deleteTexture();
         delete layer;
     }
 }
@@ -93,29 +93,23 @@
         mCache.removeAt(index);
 
         layer = entry.mLayer;
-        mSize -= layer->width * layer->height * 4;
+        mSize -= layer->getWidth() * layer->getHeight() * 4;
 
-        LAYER_LOGD("Reusing layer %dx%d", layer->width, layer->height);
+        LAYER_LOGD("Reusing layer %dx%d", layer->getWidth(), layer->getHeight());
     } else {
         LAYER_LOGD("Creating new layer %dx%d", entry.mWidth, entry.mHeight);
 
         layer = new Layer(entry.mWidth, entry.mHeight);
-        layer->blend = true;
-        layer->empty = true;
-        layer->fbo = 0;
-        layer->colorFilter = NULL;
+        layer->setBlend(true);
+        layer->setEmpty(true);
+        layer->setFbo(0);
 
-        glGenTextures(1, &layer->texture);
-        glBindTexture(GL_TEXTURE_2D, layer->texture);
-
+        layer->generateTexture();
+        layer->bindTexture();
+        layer->setFilter(GL_NEAREST, GL_NEAREST);
+        layer->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
         glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
 #if DEBUG_LAYERS
         size_t size = mCache.size();
         for (size_t i = 0; i < size; i++) {
@@ -133,30 +127,30 @@
     //       size already in the cache, and reuse it instead of creating a new one
 
     LayerEntry entry(width, height);
-    if (entry.mWidth <= layer->width && entry.mHeight <= layer->height) {
+    if (entry.mWidth <= layer->getWidth() && entry.mHeight <= layer->getHeight()) {
         return true;
     }
 
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, layer->texture);
+    uint32_t oldWidth = layer->getWidth();
+    uint32_t oldHeight = layer->getHeight();
 
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, entry.mWidth, entry.mHeight, 0,
-            GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+    glActiveTexture(GL_TEXTURE0);
+    layer->bindTexture();
+    layer->setSize(entry.mWidth, entry.mHeight);
+    layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
 
     if (glGetError() != GL_NO_ERROR) {
+        layer->setSize(oldWidth, oldHeight);
         return false;
     }
 
-    layer->width = entry.mWidth;
-    layer->height = entry.mHeight;
-
     return true;
 }
 
 bool LayerCache::put(Layer* layer) {
-    if (!layer->isCacheable) return false;
+    if (!layer->isCacheable()) return false;
 
-    const uint32_t size = layer->width * layer->height * 4;
+    const uint32_t size = layer->getWidth() * layer->getHeight() * 4;
     // Don't even try to cache a layer that's bigger than the cache
     if (size < mMaxSize) {
         // TODO: Use an LRU
diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h
index d2d5f39..81b8bf3 100644
--- a/libs/hwui/LayerCache.h
+++ b/libs/hwui/LayerCache.h
@@ -119,7 +119,7 @@
         }
 
         LayerEntry(Layer* layer):
-            mLayer(layer), mWidth(layer->width), mHeight(layer->height) {
+            mLayer(layer), mWidth(layer->getWidth()), mHeight(layer->getHeight()) {
         }
 
         bool operator<(const LayerEntry& rhs) const {
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index e034a868..44f2a40 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -32,9 +32,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
-    LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo);
+    LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->getFbo());
 
-    glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo);
+    glBindFramebuffer(GL_FRAMEBUFFER, mLayer->getFbo());
 
     const float width = mLayer->layer.getWidth();
     const float height = mLayer->layer.getHeight();
@@ -62,14 +62,14 @@
 
     generateMesh();
 
-    LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mLayer->fbo);
+    LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mLayer->getFbo());
 
     // No need to unbind our FBO, this will be taken care of by the caller
     // who will invoke OpenGLRenderer::resume()
 }
 
 GLint LayerRenderer::getTargetFbo() {
-    return mLayer->fbo;
+    return mLayer->getFbo();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -128,8 +128,8 @@
     }
     mLayer->meshElementCount = elementCount;
 
-    const float texX = 1.0f / float(mLayer->width);
-    const float texY = 1.0f / float(mLayer->height);
+    const float texX = 1.0f / float(mLayer->getWidth());
+    const float texY = 1.0f / float(mLayer->getHeight());
     const float height = mLayer->layer.getHeight();
 
     TextureVertex* mesh = mLayer->mesh;
@@ -182,40 +182,41 @@
         return NULL;
     }
 
-    layer->fbo = fbo;
+    layer->setFbo(fbo);
     layer->layer.set(0.0f, 0.0f, width, height);
-    layer->texCoords.set(0.0f, height / float(layer->height),
-            width / float(layer->width), 0.0f);
-    layer->alpha = 255;
-    layer->mode = SkXfermode::kSrcOver_Mode;
-    layer->blend = !isOpaque;
-    layer->colorFilter = NULL;
+    layer->texCoords.set(0.0f, height / float(layer->getHeight()),
+            width / float(layer->getWidth()), 0.0f);
+    layer->setAlpha(255, SkXfermode::kSrcOver_Mode);
+    layer->setBlend(!isOpaque);
+    layer->setColorFilter(NULL);
     layer->region.clear();
 
     GLuint previousFbo;
     glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo);
 
-    glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo);
-    glBindTexture(GL_TEXTURE_2D, layer->texture);
+    glBindFramebuffer(GL_FRAMEBUFFER, layer->getFbo());
+    layer->bindTexture();
 
     // Initialize the texture if needed
-    if (layer->empty) {
-        layer->empty = false;
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, layer->width, layer->height, 0,
-                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+    if (layer->isEmpty()) {
+        layer->setEmpty(false);
+        layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
 
         if (glGetError() != GL_NO_ERROR) {
             LOGD("Could not allocate texture");
+
             glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
-            glDeleteTextures(1, &layer->texture);
             Caches::getInstance().fboCache.put(fbo);
+
+            layer->deleteTexture();
             delete layer;
+
             return NULL;
         }
     }
 
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-            layer->texture, 0);
+            layer->getTexture(), 0);
 
     glDisable(GL_SCISSOR_TEST);
     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -229,14 +230,14 @@
 
 bool LayerRenderer::resizeLayer(Layer* layer, uint32_t width, uint32_t height) {
     if (layer) {
-        LAYER_RENDERER_LOGD("Resizing layer fbo = %d to %dx%d", layer->fbo, width, height);
+        LAYER_RENDERER_LOGD("Resizing layer fbo = %d to %dx%d", layer->getFbo(), width, height);
 
         if (Caches::getInstance().layerCache.resize(layer, width, height)) {
             layer->layer.set(0.0f, 0.0f, width, height);
-            layer->texCoords.set(0.0f, height / float(layer->height),
-                    width / float(layer->width), 0.0f);
+            layer->texCoords.set(0.0f, height / float(layer->getHeight()),
+                    width / float(layer->getWidth()), 0.0f);
         } else {
-            if (layer->texture) glDeleteTextures(1, &layer->texture);
+            layer->deleteTexture();
             delete layer;
             return false;
         }
@@ -245,37 +246,23 @@
     return true;
 }
 
-static void setTextureParameters(Layer* layer) {
-    glBindTexture(layer->renderTarget, layer->texture);
-
-    glTexParameteri(layer->renderTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(layer->renderTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-    glTexParameteri(layer->renderTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(layer->renderTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-}
-
 Layer* LayerRenderer::createTextureLayer(bool isOpaque) {
     LAYER_RENDERER_LOGD("Creating new texture layer");
 
     Layer* layer = new Layer(0, 0);
-    layer->isCacheable = false;
-    layer->isTextureLayer = true;
-    layer->blend = !isOpaque;
-    layer->empty = true;
-    layer->fbo = 0;
-    layer->colorFilter = NULL;
-    layer->fbo = 0;
+    layer->setCacheable(false);
+    layer->setTextureLayer(true);
+    layer->setBlend(!isOpaque);
+    layer->setEmpty(true);
+    layer->setFbo(0);
+    layer->setAlpha(255, SkXfermode::kSrcOver_Mode);
     layer->layer.set(0.0f, 0.0f, 0.0f, 0.0f);
     layer->texCoords.set(0.0f, 1.0f, 0.0f, 1.0f);
-    layer->alpha = 255;
-    layer->mode = SkXfermode::kSrcOver_Mode;
-    layer->colorFilter = NULL;
     layer->region.clear();
-    layer->renderTarget = GL_NONE; // see ::updateTextureLayer()
+    layer->setRenderTarget(GL_NONE); // see ::updateTextureLayer()
 
     glActiveTexture(GL_TEXTURE0);
-    glGenTextures(1, &layer->texture);
+    layer->generateTexture();
 
     return layer;
 }
@@ -283,31 +270,32 @@
 void LayerRenderer::updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
         bool isOpaque, GLenum renderTarget, float* transform) {
     if (layer) {
-        layer->blend = !isOpaque;
-        layer->width = width;
-        layer->height = height;
+        layer->setBlend(!isOpaque);
+        layer->setSize(width, height);
         layer->layer.set(0.0f, 0.0f, width, height);
         layer->region.set(width, height);
         layer->regionRect.set(0.0f, 0.0f, width, height);
-        layer->texTransform.load(transform);
+        layer->getTexTransform().load(transform);
 
-        if (renderTarget != layer->renderTarget) {
-            layer->renderTarget = renderTarget;
-            setTextureParameters(layer);
+        if (renderTarget != layer->getRenderTarget()) {
+            layer->setRenderTarget(renderTarget);
+            layer->bindTexture();
+            layer->setFilter(GL_NEAREST, GL_NEAREST, false, true);
+            layer->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, false, true);
         }
     }
 }
 
 void LayerRenderer::destroyLayer(Layer* layer) {
     if (layer) {
-        LAYER_RENDERER_LOGD("Destroying layer, fbo = %d", layer->fbo);
+        LAYER_RENDERER_LOGD("Destroying layer, fbo = %d", layer->getFbo());
 
-        if (layer->fbo) {
-            Caches::getInstance().fboCache.put(layer->fbo);
+        if (layer->getFbo()) {
+            Caches::getInstance().fboCache.put(layer->getFbo());
         }
 
         if (!Caches::getInstance().layerCache.put(layer)) {
-            if (layer->texture) glDeleteTextures(1, &layer->texture);
+            layer->deleteTexture();
             delete layer;
         } else {
             layer->region.clear();
@@ -317,7 +305,7 @@
 
 void LayerRenderer::destroyLayerDeferred(Layer* layer) {
     if (layer) {
-        LAYER_RENDERER_LOGD("Deferring layer destruction, fbo = %d", layer->fbo);
+        LAYER_RENDERER_LOGD("Deferring layer destruction, fbo = %d", layer->getFbo());
 
         Caches::getInstance().deleteLayerDeferred(layer);
     }
@@ -325,7 +313,7 @@
 
 bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) {
     Caches& caches = Caches::getInstance();
-    if (layer && layer->isTextureLayer && bitmap->width() <= caches.maxTextureSize &&
+    if (layer && layer->isTextureLayer() && bitmap->width() <= caches.maxTextureSize &&
             bitmap->height() <= caches.maxTextureSize) {
 
         GLuint fbo = caches.fboCache.get();
@@ -365,12 +353,11 @@
                 break;
         }
 
-        float alpha = layer->alpha;
-        SkXfermode::Mode mode = layer->mode;
+        float alpha = layer->getAlpha();
+        SkXfermode::Mode mode = layer->getMode();
 
-        layer->mode = SkXfermode::kSrc_Mode;
-        layer->alpha = 255;
-        layer->fbo = fbo;
+        layer->setAlpha(255, SkXfermode::kSrc_Mode);
+        layer->setFbo(fbo);
 
         glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo);
         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
@@ -399,7 +386,7 @@
             LayerRenderer renderer(layer);
             renderer.setViewport(bitmap->width(), bitmap->height());
             renderer.OpenGLRenderer::prepareDirty(0.0f, 0.0f,
-                    bitmap->width(), bitmap->height(), !layer->blend);
+                    bitmap->width(), bitmap->height(), !layer->isBlend());
             if ((error = glGetError()) != GL_NO_ERROR) goto error;
 
             {
@@ -424,9 +411,8 @@
 #endif
 
         glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
-        layer->mode = mode;
-        layer->alpha = alpha;
-        layer->fbo = 0;
+        layer->setAlpha(alpha, mode);
+        layer->setFbo(0);
         glDeleteTextures(1, &texture);
         caches.fboCache.put(fbo);
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 1c06a0b..cb5a82b 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -449,12 +449,11 @@
         return false;
     }
 
-    layer->mode = mode;
-    layer->alpha = alpha;
+    layer->setAlpha(alpha, mode);
     layer->layer.set(bounds);
-    layer->texCoords.set(0.0f, bounds.getHeight() / float(layer->height),
-            bounds.getWidth() / float(layer->width), 0.0f);
-    layer->colorFilter = mColorFilter;
+    layer->texCoords.set(0.0f, bounds.getHeight() / float(layer->getHeight()),
+            bounds.getWidth() / float(layer->getWidth()), 0.0f);
+    layer->setColorFilter(mColorFilter);
 
     // Save the layer in the snapshot
     snapshot->flags |= Snapshot::kFlagIsLayer;
@@ -464,12 +463,13 @@
         return createFboLayer(layer, bounds, snapshot, previousFbo);
     } else {
         // Copy the framebuffer into the layer
-        glBindTexture(GL_TEXTURE_2D, layer->texture);
+        layer->bindTexture();
         if (!bounds.isEmpty()) {
-            if (layer->empty) {
-                glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left,
-                        snapshot->height - bounds.bottom, layer->width, layer->height, 0);
-                layer->empty = false;
+            if (layer->isEmpty()) {
+                glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+                        bounds.left, snapshot->height - bounds.bottom,
+                        layer->getWidth(), layer->getHeight(), 0);
+                layer->setEmpty(false);
             } else {
                 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left,
                         snapshot->height - bounds.bottom, bounds.getWidth(), bounds.getHeight());
@@ -485,7 +485,7 @@
 
 bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, sp<Snapshot> snapshot,
         GLuint previousFbo) {
-    layer->fbo = mCaches.fboCache.get();
+    layer->setFbo(mCaches.fboCache.get());
 
 #if RENDER_LAYERS_AS_REGIONS
     snapshot->region = &snapshot->layer->region;
@@ -507,7 +507,7 @@
     clip.translate(-bounds.left, -bounds.top);
 
     snapshot->flags |= Snapshot::kFlagIsFboLayer;
-    snapshot->fbo = layer->fbo;
+    snapshot->fbo = layer->getFbo();
     snapshot->resetTransform(-bounds.left, -bounds.top, 0.0f);
     snapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom);
     snapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
@@ -516,18 +516,17 @@
     snapshot->orthoMatrix.load(mOrthoMatrix);
 
     // Bind texture to FBO
-    glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo);
-    glBindTexture(GL_TEXTURE_2D, layer->texture);
+    glBindFramebuffer(GL_FRAMEBUFFER, layer->getFbo());
+    layer->bindTexture();
 
     // Initialize the texture if needed
-    if (layer->empty) {
-        layer->empty = false;
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, layer->width, layer->height, 0,
-                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+    if (layer->isEmpty()) {
+        layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
+        layer->setEmpty(false);
     }
 
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-            layer->texture, 0);
+            layer->getTexture(), 0);
 
 #if DEBUG_LAYERS_AS_REGIONS
     GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -535,8 +534,8 @@
         LOGE("Framebuffer incomplete (GL error code 0x%x)", status);
 
         glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
-        glDeleteTextures(1, &layer->texture);
-        mCaches.fboCache.put(layer->fbo);
+        layer->deleteTexture();
+        mCaches.fboCache.put(layer->getFbo());
 
         delete layer;
 
@@ -578,11 +577,11 @@
     Layer* layer = current->layer;
     const Rect& rect = layer->layer;
 
-    if (!fboLayer && layer->alpha < 255) {
+    if (!fboLayer && layer->getAlpha() < 255) {
         drawColorRect(rect.left, rect.top, rect.right, rect.bottom,
-                layer->alpha << 24, SkXfermode::kDstIn_Mode, true);
+                layer->getAlpha() << 24, SkXfermode::kDstIn_Mode, true);
         // Required below, composeLayerRect() will divide by 255
-        layer->alpha = 255;
+        layer->setAlpha(255);
     }
 
     mCaches.unbindMeshBuffer();
@@ -593,18 +592,16 @@
     // drawing only the dirty region
     if (fboLayer) {
         dirtyLayer(rect.left, rect.top, rect.right, rect.bottom, *previous->transform);
-        if (layer->colorFilter) {
-            setupColorFilter(layer->colorFilter);
+        if (layer->getColorFilter()) {
+            setupColorFilter(layer->getColorFilter());
         }
         composeLayerRegion(layer, rect);
-        if (layer->colorFilter) {
+        if (layer->getColorFilter()) {
             resetColorFilter();
         }
-    } else {
-        if (!rect.isEmpty()) {
-            dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
-            composeLayerRect(layer, rect, true);
-        }
+    } else if (!rect.isEmpty()) {
+        dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
+        composeLayerRect(layer, rect, true);
     }
 
     if (fboLayer) {
@@ -622,16 +619,16 @@
     // Failing to add the layer to the cache should happen only if the layer is too large
     if (!mCaches.layerCache.put(layer)) {
         LAYER_LOGD("Deleting layer");
-        glDeleteTextures(1, &layer->texture);
+        layer->deleteTexture();
         delete layer;
     }
 }
 
 void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) {
-    float alpha = layer->alpha / 255.0f;
+    float alpha = layer->getAlpha() / 255.0f;
 
     setupDraw();
-    if (layer->renderTarget == GL_TEXTURE_2D) {
+    if (layer->getRenderTarget() == GL_TEXTURE_2D) {
         setupDrawWithTexture();
     } else {
         setupDrawWithExternalTexture();
@@ -639,17 +636,26 @@
     setupDrawTextureTransform();
     setupDrawColor(alpha, alpha, alpha, alpha);
     setupDrawColorFilter();
-    setupDrawBlending(layer->blend || layer->alpha < 255, layer->mode);
+    setupDrawBlending(layer->isBlend() || alpha < 1.0f, layer->getMode());
     setupDrawProgram();
-    setupDrawModelView(rect.left, rect.top, rect.right, rect.bottom);
     setupDrawPureColorUniforms();
     setupDrawColorFilterUniforms();
-    if (layer->renderTarget == GL_TEXTURE_2D) {
-        setupDrawTexture(layer->texture);
+    if (layer->getRenderTarget() == GL_TEXTURE_2D) {
+        setupDrawTexture(layer->getTexture());
     } else {
-        setupDrawExternalTexture(layer->texture);
+        setupDrawExternalTexture(layer->getTexture());
     }
-    setupDrawTextureTransformUniforms(layer->texTransform);
+    if (mSnapshot->transform->isPureTranslate()) {
+        const float x = (int) floorf(rect.left + mSnapshot->transform->getTranslateX() + 0.5f);
+        const float y = (int) floorf(rect.top + mSnapshot->transform->getTranslateY() + 0.5f);
+
+        layer->setFilter(GL_NEAREST, GL_NEAREST);
+        setupDrawModelView(x, y, x + rect.getWidth(), y + rect.getHeight(), true);
+    } else {
+        layer->setFilter(GL_LINEAR, GL_LINEAR);
+        setupDrawModelView(rect.left, rect.top, rect.right, rect.bottom);
+    }
+    setupDrawTextureTransformUniforms(layer->getTexTransform());
     setupDrawMesh(&mMeshVertices[0].position[0], &mMeshVertices[0].texture[0]);
 
     glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
@@ -658,14 +664,32 @@
 }
 
 void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) {
-    if (!layer->isTextureLayer) {
+    if (!layer->isTextureLayer()) {
         const Rect& texCoords = layer->texCoords;
         resetDrawTextureTexCoords(texCoords.left, texCoords.top,
                 texCoords.right, texCoords.bottom);
 
-        drawTextureMesh(rect.left, rect.top, rect.right, rect.bottom, layer->texture,
-                layer->alpha / 255.0f, layer->mode, layer->blend, &mMeshVertices[0].position[0],
-                &mMeshVertices[0].texture[0], GL_TRIANGLE_STRIP, gMeshCount, swap, swap);
+        float x = rect.left;
+        float y = rect.top;
+        bool simpleTransform = mSnapshot->transform->isPureTranslate();
+
+        if (simpleTransform) {
+            // When we're swapping, the layer is already in screen coordinates
+            if (!swap) {
+                x = (int) floorf(rect.left + mSnapshot->transform->getTranslateX() + 0.5f);
+                y = (int) floorf(rect.top + mSnapshot->transform->getTranslateY() + 0.5f);
+            }
+
+            layer->setFilter(GL_NEAREST, GL_NEAREST, true);
+        } else {
+            layer->setFilter(GL_LINEAR, GL_LINEAR, true);
+        }
+
+        drawTextureMesh(x, y, x + rect.getWidth(), y + rect.getHeight(),
+                layer->getTexture(), layer->getAlpha() / 255.0f,
+                layer->getMode(), layer->isBlend(),
+                &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
+                GL_TRIANGLE_STRIP, gMeshCount, swap, swap || simpleTransform);
 
         resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
     } else {
@@ -690,9 +714,9 @@
         size_t count;
         const android::Rect* rects = layer->region.getArray(&count);
 
-        const float alpha = layer->alpha / 255.0f;
-        const float texX = 1.0f / float(layer->width);
-        const float texY = 1.0f / float(layer->height);
+        const float alpha = layer->getAlpha() / 255.0f;
+        const float texX = 1.0f / float(layer->getWidth());
+        const float texY = 1.0f / float(layer->getHeight());
         const float height = rect.getHeight();
 
         TextureVertex* mesh = mCaches.getRegionMesh();
@@ -702,13 +726,22 @@
         setupDrawWithTexture();
         setupDrawColor(alpha, alpha, alpha, alpha);
         setupDrawColorFilter();
-        setupDrawBlending(layer->blend || layer->alpha < 255, layer->mode, false);
+        setupDrawBlending(layer->isBlend() || alpha < 1.0f, layer->getMode(), false);
         setupDrawProgram();
         setupDrawDirtyRegionsDisabled();
         setupDrawPureColorUniforms();
         setupDrawColorFilterUniforms();
-        setupDrawTexture(layer->texture);
-        setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom);
+        setupDrawTexture(layer->getTexture());
+        if (mSnapshot->transform->isPureTranslate()) {
+            const float x = (int) floorf(rect.left + mSnapshot->transform->getTranslateX() + 0.5f);
+            const float y = (int) floorf(rect.top + mSnapshot->transform->getTranslateY() + 0.5f);
+
+            layer->setFilter(GL_NEAREST, GL_NEAREST);
+            setupDrawModelViewTranslate(x, y, x + rect.getWidth(), y + rect.getHeight(), true);
+        } else {
+            layer->setFilter(GL_LINEAR, GL_LINEAR);
+            setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom);
+        }
         setupDrawMesh(&mesh[0].position[0], &mesh[0].texture[0]);
 
         for (size_t i = 0; i < count; i++) {
@@ -2154,8 +2187,7 @@
     SkXfermode::Mode mode;
     getAlphaAndMode(paint, &alpha, &mode);
 
-    layer->alpha = alpha;
-    layer->mode = mode;
+    layer->setAlpha(alpha, mode);
 
 #if RENDER_LAYERS_AS_REGIONS
     if (!layer->region.isEmpty()) {
@@ -2169,13 +2201,23 @@
             setupDrawWithTexture();
             setupDrawColor(a, a, a, a);
             setupDrawColorFilter();
-            setupDrawBlending(layer->blend || layer->alpha < 255, layer->mode, false);
+            setupDrawBlending(layer->isBlend() || a < 1.0f, layer->getMode(), false);
             setupDrawProgram();
-            setupDrawModelViewTranslate(x, y,
-                    x + layer->layer.getWidth(), y + layer->layer.getHeight());
             setupDrawPureColorUniforms();
             setupDrawColorFilterUniforms();
-            setupDrawTexture(layer->texture);
+            setupDrawTexture(layer->getTexture());
+            if (mSnapshot->transform->isPureTranslate()) {
+                x = (int) floorf(x + mSnapshot->transform->getTranslateX() + 0.5f);
+                y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f);
+
+                layer->setFilter(GL_NEAREST, GL_NEAREST);
+                setupDrawModelViewTranslate(x, y,
+                        x + layer->layer.getWidth(), y + layer->layer.getHeight(), true);
+            } else {
+                layer->setFilter(GL_LINEAR, GL_LINEAR);
+                setupDrawModelViewTranslate(x, y,
+                        x + layer->layer.getWidth(), y + layer->layer.getHeight());
+            }
             setupDrawMesh(&layer->mesh[0].position[0], &layer->mesh[0].texture[0]);
 
             glDrawElements(GL_TRIANGLES, layer->meshElementCount,
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 4922bb3..c6ae326 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -29,8 +29,22 @@
     Texture() {
         cleanup = false;
         bitmapSize = 0;
+
         wrapS = GL_CLAMP_TO_EDGE;
         wrapT = GL_CLAMP_TO_EDGE;
+
+        minFilter = GL_NEAREST;
+        magFilter = GL_NEAREST;
+    }
+
+    void setWrap(GLenum wrapS, GLenum wrapT) {
+        this->wrapS = wrapS;
+        this->wrapT = wrapT;
+    }
+
+    void setFilter(GLenum min, GLenum mag) {
+        minFilter = min;
+        magFilter = mag;
     }
 
     /**
@@ -67,6 +81,12 @@
      */
     GLenum wrapS;
     GLenum wrapT;
+
+    /**
+     * Last filters set on this texture. Defaults to GL_NEAREST.
+     */
+    GLenum minFilter;
+    GLenum magFilter;
 }; // struct Texture
 
 class AutoTexture {
diff --git a/media/jni/audioeffect/Android.mk b/media/jni/audioeffect/Android.mk
index 4c5cf71..3e493b1 100644
--- a/media/jni/audioeffect/Android.mk
+++ b/media/jni/audioeffect/Android.mk
@@ -12,6 +12,9 @@
 	libnativehelper \
 	libmedia
 
+LOCAL_C_INCLUDES := \
+	system/media/audio_effects/include
+
 LOCAL_MODULE:= libaudioeffect_jni
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/lvm/wrapper/Android.mk b/media/libeffects/lvm/wrapper/Android.mk
index 99cfdfa..ab13605 100644
--- a/media/libeffects/lvm/wrapper/Android.mk
+++ b/media/libeffects/lvm/wrapper/Android.mk
@@ -30,7 +30,8 @@
 LOCAL_C_INCLUDES += \
 	$(LOCAL_PATH)/Bundle \
 	$(LOCAL_PATH)/../lib/Common/lib/ \
-	$(LOCAL_PATH)/../lib/Bundle/lib/
+	$(LOCAL_PATH)/../lib/Bundle/lib/ \
+	system/media/audio_effects/include
 
 
 include $(BUILD_SHARED_LIBRARY)
@@ -64,6 +65,6 @@
     $(LOCAL_PATH)/Reverb \
     $(LOCAL_PATH)/../lib/Common/lib/ \
     $(LOCAL_PATH)/../lib/Reverb/lib/ \
-
+    system/media/audio_effects/include
 
 include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
index 2b51029..5634ca1 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
@@ -17,9 +17,9 @@
 #ifndef ANDROID_EFFECTBUNDLE_H_
 #define ANDROID_EFFECTBUNDLE_H_
 
-#include <media/EffectEqualizerApi.h>
-#include <media/EffectBassBoostApi.h>
-#include <media/EffectVirtualizerApi.h>
+#include <audio_effects/effect_bassboost.h>
+#include <audio_effects/effect_equalizer.h>
+#include <audio_effects/effect_virtualizer.h>
 #include <LVM.h>
 #include <limits.h>
 
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.h b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.h
index 093992b..7c15b18 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.h
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.h
@@ -17,8 +17,8 @@
 #ifndef ANDROID_EFFECTREVERB_H_
 #define ANDROID_EFFECTREVERB_H_
 
-#include <media/EffectEnvironmentalReverbApi.h>
-#include <media/EffectPresetReverbApi.h>
+#include <audio_effects/effect_environmentalreverb.h>
+#include <audio_effects/effect_presetreverb.h>
 
 #if __cplusplus
 extern "C" {
diff --git a/media/libeffects/testlibs/Android.mk_ b/media/libeffects/testlibs/Android.mk_
index 98d477b..249ebf4 100644
--- a/media/libeffects/testlibs/Android.mk_
+++ b/media/libeffects/testlibs/Android.mk_
@@ -23,6 +23,7 @@
 endif
 
 LOCAL_C_INCLUDES := \
+	system/media/audio_effects/include \
 	$(call include-path-for, graphics corecg)
 
 LOCAL_MODULE_TAGS := optional
@@ -58,7 +59,8 @@
 endif
 
 LOCAL_C_INCLUDES := \
-	$(call include-path-for, graphics corecg)
+	$(call include-path-for, graphics corecg) \
+	system/media/audio_effects/include
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/media/libeffects/testlibs/EffectEqualizer.cpp b/media/libeffects/testlibs/EffectEqualizer.cpp
index 43dfa82..c2ffce5 100644
--- a/media/libeffects/testlibs/EffectEqualizer.cpp
+++ b/media/libeffects/testlibs/EffectEqualizer.cpp
@@ -26,7 +26,8 @@
 #include "AudioEqualizer.h"
 #include "AudioBiquadFilter.h"
 #include "AudioFormatAdapter.h"
-#include <media/EffectEqualizerApi.h>
+#include <audio_effects/effect_equalizer.h>
+
 
 // effect_handle_t interface implementation for equalizer effect
 extern "C" const struct effect_interface_s gEqualizerInterface;
diff --git a/media/libeffects/testlibs/EffectReverb.h b/media/libeffects/testlibs/EffectReverb.h
index a239814..8e2cc31 100644
--- a/media/libeffects/testlibs/EffectReverb.h
+++ b/media/libeffects/testlibs/EffectReverb.h
@@ -17,8 +17,8 @@
 #ifndef ANDROID_EFFECTREVERB_H_
 #define ANDROID_EFFECTREVERB_H_
 
-#include <media/EffectEnvironmentalReverbApi.h>
-#include <media/EffectPresetReverbApi.h>
+#include <audio_effects/effect_environmentalreverb.h>
+#include <audio_effects/effect_presetreverb.h>
 
 
 /*------------------------------------
diff --git a/media/libeffects/visualizer/Android.mk b/media/libeffects/visualizer/Android.mk
index 3a0f438..dff585f 100644
--- a/media/libeffects/visualizer/Android.mk
+++ b/media/libeffects/visualizer/Android.mk
@@ -23,8 +23,8 @@
 endif
 
 LOCAL_C_INCLUDES := \
-	$(call include-path-for, graphics corecg)
-
+	$(call include-path-for, graphics corecg) \
+	system/media/audio_effects/include
 
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 80d1f69..aeebd4d 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -21,7 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <new>
-#include <media/EffectVisualizerApi.h>
+#include <audio_effects/effect_visualizer.h>
 
 
 extern "C" {
@@ -375,7 +375,7 @@
         p->status = 0;
         *replySize = sizeof(effect_param_t) + sizeof(uint32_t);
         if (p->psize != sizeof(uint32_t) ||
-            *(uint32_t *)p->data != VISU_PARAM_CAPTURE_SIZE) {
+            *(uint32_t *)p->data != VISUALIZER_PARAM_CAPTURE_SIZE) {
             p->status = -EINVAL;
             break;
         }
@@ -394,7 +394,7 @@
         effect_param_t *p = (effect_param_t *)pCmdData;
         if (p->psize != sizeof(uint32_t) ||
             p->vsize != sizeof(uint32_t) ||
-            *(uint32_t *)p->data != VISU_PARAM_CAPTURE_SIZE) {
+            *(uint32_t *)p->data != VISUALIZER_PARAM_CAPTURE_SIZE) {
             *(int32_t *)pReplyData = -EINVAL;
             break;;
         }
@@ -407,9 +407,9 @@
         break;
 
 
-    case VISU_CMD_CAPTURE:
+    case VISUALIZER_CMD_CAPTURE:
         if (pReplyData == NULL || *replySize != pContext->mCaptureSize) {
-            LOGV("VISU_CMD_CAPTURE() error *replySize %d pContext->mCaptureSize %d",
+            LOGV("VISUALIZER_CMD_CAPTURE() error *replySize %d pContext->mCaptureSize %d",
                     *replySize, pContext->mCaptureSize);
             return -EINVAL;
         }
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 121e38a4..f7c54fa 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -68,6 +68,7 @@
     $(call include-path-for, graphics corecg) \
     $(TOP)/frameworks/base/include/media/stagefright/openmax \
     external/icu4c/common \
-    external/expat/lib
+    external/expat/lib \
+    system/media/audio_effects/include
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp
index 366707c..bf40481 100644
--- a/media/libmedia/Visualizer.cpp
+++ b/media/libmedia/Visualizer.cpp
@@ -143,7 +143,7 @@
 
     p->psize = sizeof(uint32_t);
     p->vsize = sizeof(uint32_t);
-    *(int32_t *)p->data = VISU_PARAM_CAPTURE_SIZE;
+    *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE;
     *((int32_t *)p->data + 1)= size;
     status_t status = setParameter(p);
 
@@ -171,7 +171,7 @@
     status_t status = NO_ERROR;
     if (mEnabled) {
         uint32_t replySize = mCaptureSize;
-        status = command(VISU_CMD_CAPTURE, 0, NULL, &replySize, waveform);
+        status = command(VISUALIZER_CMD_CAPTURE, 0, NULL, &replySize, waveform);
         LOGV("getWaveForm() command returned %d", status);
         if (replySize == 0) {
             status = NOT_ENOUGH_DATA;
@@ -276,7 +276,7 @@
 
     p->psize = sizeof(uint32_t);
     p->vsize = sizeof(uint32_t);
-    *(int32_t *)p->data = VISU_PARAM_CAPTURE_SIZE;
+    *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE;
     status_t status = getParameter(p);
 
     if (status == NO_ERROR) {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 408436a..6190c9bb 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -318,7 +318,11 @@
     }
 
     private Drawable getFullResIcon(Resources resources, int iconId) {
-        return resources.getDrawableForDensity(iconId, mIconDpi);
+        try {
+            return resources.getDrawableForDensity(iconId, mIconDpi);
+        } catch (Resources.NotFoundException e) {
+            return getFullResDefaultActivityIcon();
+        }
     }
 
     private Drawable getFullResIcon(ResolveInfo info, PackageManager packageManager) {
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 2222e8b..75d24a1 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -10,6 +10,9 @@
     AudioResamplerCubic.cpp.arm \
     AudioPolicyService.cpp
 
+LOCAL_C_INCLUDES := \
+    system/media/audio_effects/include
+
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
     libutils \
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f716e63..daf94f2 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -50,7 +50,7 @@
 #include "AudioFlinger.h"
 
 #include <media/EffectsFactoryApi.h>
-#include <media/EffectVisualizerApi.h>
+#include <audio_effects/effect_visualizer.h>
 
 // ----------------------------------------------------------------------------
 
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java
index c857ded..95b84c4 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java
@@ -62,7 +62,9 @@
             }
         });
 
-        mContent.addView(mTextureView, new FrameLayout.LayoutParams(500, 400, Gravity.CENTER));
+        mContent.addView(mTextureView, new FrameLayout.LayoutParams(
+                FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT,
+                Gravity.CENTER));
         mContent.addView(button, new FrameLayout.LayoutParams(
                 FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT,
                 Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM));
@@ -72,6 +74,9 @@
     @Override
     public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
         mCamera = Camera.open();
+        Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
+        mTextureView.setLayoutParams(new FrameLayout.LayoutParams(
+                previewSize.width, previewSize.height, Gravity.CENTER));
 
         try {
             mCamera.setPreviewTexture(surface);
@@ -82,20 +87,6 @@
         mCamera.startPreview();
 
         mTextureView.setCameraDistance(5000);
-
-//        ObjectAnimator rotationY = ObjectAnimator.ofFloat(mTextureView, "rotationY", 0.0f, 360.0f);
-//        rotationY.setRepeatMode(ObjectAnimator.REVERSE);
-//        rotationY.setRepeatCount(ObjectAnimator.INFINITE);
-//        rotationY.setDuration(4000);
-
-//        ObjectAnimator alpha = ObjectAnimator.ofFloat(mTextureView, "alpha", 1.0f, 0.0f);
-//        alpha.setRepeatMode(ObjectAnimator.REVERSE);
-//        alpha.setRepeatCount(ObjectAnimator.INFINITE);
-//        alpha.setDuration(4000);
-
-//        mAnimatorSet = new AnimatorSet();
-//        mAnimatorSet.play(alpha).with(rotationY);
-//        mAnimatorSet.start();
     }
 
     @Override