Merge "Typo in TextAppearanceSpan documentation"
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 7b404b4..1a84175 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2203,10 +2203,10 @@
     }
 
     /**
-     * Perform dispatching of a {@link #saveHierarchyState freeze()} to only this view,
-     * not to its children.  For use when overriding
-     * {@link #dispatchSaveInstanceState dispatchFreeze()} to allow subclasses to freeze
-     * their own state but not the state of their children.
+     * Perform dispatching of a {@link #saveHierarchyState(android.util.SparseArray)}  freeze()}
+     * to only this view, not to its children.  For use when overriding
+     * {@link #dispatchSaveInstanceState(android.util.SparseArray)}  dispatchFreeze()} to allow
+     * subclasses to freeze their own state but not the state of their children.
      *
      * @param container the container
      */
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 1fe6f4b..d8068f9 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -218,15 +218,16 @@
     
     /**
      * An optional argument to supply a maximum width for this view. Only valid if
-     * {@link #setAdjustViewBounds} has been set to true. To set an image to be a maximum of 100 x
-     * 100 while preserving the original aspect ratio, do the following: 1) set adjustViewBounds to
-     * true 2) set maxWidth and maxHeight to 100 3) set the height and width layout params to
-     * WRAP_CONTENT.
+     * {@link #setAdjustViewBounds(boolean)} has been set to true. To set an image to be a maximum
+     * of 100 x 100 while preserving the original aspect ratio, do the following: 1) set
+     * adjustViewBounds to true 2) set maxWidth and maxHeight to 100 3) set the height and width
+     * layout params to WRAP_CONTENT.
      * 
      * <p>
      * Note that this view could be still smaller than 100 x 100 using this approach if the original
      * image is small. To set an image to a fixed size, specify that size in the layout params and
-     * then use {@link #setScaleType} to determine how to fit the image within the bounds.
+     * then use {@link #setScaleType(android.widget.ImageView.ScaleType)} to determine how to fit
+     * the image within the bounds.
      * </p>
      * 
      * @param maxWidth maximum width for this view
@@ -240,15 +241,16 @@
     
     /**
      * An optional argument to supply a maximum height for this view. Only valid if
-     * {@link #setAdjustViewBounds} has been set to true. To set an image to be a maximum of 100 x
-     * 100 while preserving the original aspect ratio, do the following: 1) set adjustViewBounds to
-     * true 2) set maxWidth and maxHeight to 100 3) set the height and width layout params to
-     * WRAP_CONTENT.
+     * {@link #setAdjustViewBounds(boolean)} has been set to true. To set an image to be a
+     * maximum of 100 x 100 while preserving the original aspect ratio, do the following: 1) set
+     * adjustViewBounds to true 2) set maxWidth and maxHeight to 100 3) set the height and width
+     * layout params to WRAP_CONTENT.
      * 
      * <p>
      * Note that this view could be still smaller than 100 x 100 using this approach if the original
      * image is small. To set an image to a fixed size, specify that size in the layout params and
-     * then use {@link #setScaleType} to determine how to fit the image within the bounds.
+     * then use {@link #setScaleType(android.widget.ImageView.ScaleType)} to determine how to fit
+     * the image within the bounds.
      * </p>
      * 
      * @param maxHeight maximum height for this view
@@ -272,8 +274,8 @@
      *
      * <p class="note">This does Bitmap reading and decoding on the UI
      * thread, which can cause a latency hiccup.  If that's a concern,
-     * consider using {@link #setImageDrawable} or
-     * {@link #setImageBitmap} and
+     * consider using {@link #setImageDrawable(android.graphics.drawable.Drawable)} or
+     * {@link #setImageBitmap(android.graphics.Bitmap)} and
      * {@link android.graphics.BitmapFactory} instead.</p>
      *
      * @param resId the resource identifier of the the drawable
@@ -297,8 +299,8 @@
      *
      * <p class="note">This does Bitmap reading and decoding on the UI
      * thread, which can cause a latency hiccup.  If that's a concern,
-     * consider using {@link #setImageDrawable} or
-     * {@link #setImageBitmap} and
+     * consider using {@link #setImageDrawable(android.graphics.drawable.Drawable)} or
+     * {@link #setImageBitmap(android.graphics.Bitmap)} and
      * {@link android.graphics.BitmapFactory} instead.</p>
      *
      * @param uri The Uri of an image
@@ -902,12 +904,12 @@
 
     /**
      * <p>Set the offset of the widget's text baseline from the widget's top
-     * boundary.  This value is overridden by the {@link #setBaselineAlignBottom}
+     * boundary.  This value is overridden by the {@link #setBaselineAlignBottom(boolean)}
      * property.</p>
      *
      * @param baseline The baseline to use, or -1 if none is to be provided.
      *
-     * @see #setBaseline
+     * @see #setBaseline(int) 
      * @attr ref android.R.styleable#ImageView_baseline
      */
     public void setBaseline(int baseline) {
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index b752850..c3f2360 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -237,7 +237,11 @@
 
     size_t receiveLen;
     uint32_t subID;
-    int id = rsContextGetMessage(con, buf, &receiveLen, &subID, sizeof(buf), true);
+    int id = rsContextGetMessage(con,
+                                 buf, sizeof(buf),
+                                 &receiveLen, sizeof(receiveLen),
+                                 &subID, sizeof(subID),
+                                 true);
     if (!id && receiveLen) {
         LOGV("message receive buffer too small.  %i", receiveLen);
     }
@@ -252,7 +256,11 @@
     jint *ptr = _env->GetIntArrayElements(data, NULL);
     size_t receiveLen;
     uint32_t subID;
-    int id = rsContextGetMessage(con, ptr, &receiveLen, &subID, len * 4, true);
+    int id = rsContextGetMessage(con,
+                                 ptr, len * 4,
+                                 &receiveLen, sizeof(receiveLen),
+                                 &subID, sizeof(subID),
+                                 true);
     if (!id && receiveLen) {
         LOGV("message receive buffer too small.  %i", receiveLen);
     }
@@ -266,7 +274,8 @@
     jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL);
     size_t receiveLen;
     uint32_t subID;
-    int id = rsContextPeekMessage(con, &receiveLen, &subID, wait);
+    int id = rsContextPeekMessage(con, &receiveLen, sizeof(receiveLen),
+                                  &subID, sizeof(subID), wait);
     auxDataPtr[0] = (jint)subID;
     auxDataPtr[1] = (jint)receiveLen;
     _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
@@ -426,7 +435,9 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    jint id = (jint)rsaAllocationCreateFromBitmap(con, (RsType)type, (RsAllocationMipmapControl)mip, ptr, usage);
+    jint id = (jint)rsaAllocationCreateFromBitmap(con,
+                                                  (RsType)type, (RsAllocationMipmapControl)mip,
+                                                  ptr, bitmap.getSize(), usage);
     bitmap.unlockPixels();
     return id;
 }
@@ -440,7 +451,9 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    jint id = (jint)rsaAllocationCubeCreateFromBitmap(con, (RsType)type, (RsAllocationMipmapControl)mip, ptr, usage);
+    jint id = (jint)rsaAllocationCubeCreateFromBitmap(con,
+                                                      (RsType)type, (RsAllocationMipmapControl)mip,
+                                                      ptr, bitmap.getSize(), usage);
     bitmap.unlockPixels();
     return id;
 }
diff --git a/include/media/stagefright/MediaErrors.h b/include/media/stagefright/MediaErrors.h
index 6df4d86..1a6d548 100644
--- a/include/media/stagefright/MediaErrors.h
+++ b/include/media/stagefright/MediaErrors.h
@@ -42,6 +42,17 @@
     INFO_DISCONTINUITY     = MEDIA_ERROR_BASE - 13,
 
     ERROR_NO_LICENSE       = MEDIA_ERROR_BASE - 14,
+
+    // Heartbeat Error Codes
+    HEARTBEAT_ERROR_BASE = -3000,
+
+    ERROR_HEARTBEAT_AUTHENTICATION_FAILURE                  = HEARTBEAT_ERROR_BASE,
+    ERROR_HEARTBEAT_NO_ACTIVE_PURCHASE_AGREEMENT            = HEARTBEAT_ERROR_BASE - 1,
+    ERROR_HEARTBEAT_CONCURRENT_PLAYBACK                     = HEARTBEAT_ERROR_BASE - 2,
+    ERROR_HEARTBEAT_UNUSUAL_ACTIVITY                        = HEARTBEAT_ERROR_BASE - 3,
+    ERROR_HEARTBEAT_STREAMING_UNAVAILABLE                   = HEARTBEAT_ERROR_BASE - 4,
+    ERROR_HEARTBEAT_CANNOT_ACTIVATE_RENTAL                  = HEARTBEAT_ERROR_BASE - 5,
+    ERROR_HEARTBEAT_TERMINATE_REQUESTED                     = HEARTBEAT_ERROR_BASE - 6,
 };
 
 }  // namespace android
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 26e240f..6c4a2a9 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -53,6 +53,23 @@
     }
 
     /**
+     * Sets this layer's region to a rectangle. Computes the appropriate
+     * texture coordinates.
+     */
+    void setRegionAsRect() {
+        const android::Rect& bounds = region.getBounds();
+        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 height = layer.getHeight();
+        texCoords.set(
+               regionRect.left * texX, (height - regionRect.top) * texY,
+               regionRect.right * texX, (height - regionRect.bottom) * texY);
+    }
+
+    /**
      * Bounds of the layer.
      */
     Rect layer;
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index ba110ec..ca1e7ae 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -102,19 +102,7 @@
             mLayer->meshElementCount = 0;
         }
 
-        const android::Rect& bounds = mLayer->region.getBounds();
-        mLayer->regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
-                bounds.rightBottom().x, bounds.rightBottom().y);
-
-        const float texX = 1.0f / float(mLayer->width);
-        const float texY = 1.0f / float(mLayer->height);
-        const float height = mLayer->layer.getHeight();
-        mLayer->texCoords.set(
-                mLayer->regionRect.left * texX,
-                (height - mLayer->regionRect.top) * texY,
-                mLayer->regionRect.right * texX,
-                (height - mLayer->regionRect.bottom) * texY);
-
+        mLayer->setRegionAsRect();
         return;
     }
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index dd0cca22..ea42838 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -647,10 +647,10 @@
 void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
 #if RENDER_LAYERS_AS_REGIONS
     if (layer->region.isRect()) {
-        const android::Rect& bounds = layer->region.getBounds();
-        layer->regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
-                bounds.rightBottom().x, bounds.rightBottom().y);
+        layer->setRegionAsRect();
+
         composeLayerRect(layer, layer->regionRect);
+
         layer->region.clear();
         return;
     }
@@ -979,8 +979,8 @@
     }
 }
 
-void OpenGLRenderer::setupDrawModelViewIdentity() {
-    mCaches.currentProgram->set(mOrthoMatrix, mIdentity, *mSnapshot->transform);
+void OpenGLRenderer::setupDrawModelViewIdentity(bool offset) {
+    mCaches.currentProgram->set(mOrthoMatrix, mIdentity, *mSnapshot->transform, offset);
 }
 
 void OpenGLRenderer::setupDrawModelView(float left, float top, float right, float bottom,
@@ -1389,13 +1389,46 @@
     }
 }
 
-void OpenGLRenderer::drawLinesAsQuads(float *points, int count, bool isAA, bool isHairline,
-        float strokeWidth) {
+void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
+    if (mSnapshot->isIgnored()) return;
+
+    const bool isAA = paint->isAntiAlias();
+    float strokeWidth = paint->getStrokeWidth() * 0.5f;
+    // A stroke width of 0 has a special meaning in Skia:
+    // it draws a line 1 px wide regardless of current transform
+    bool isHairLine = paint->getStrokeWidth() == 0.0f;
+    int alpha;
+    SkXfermode::Mode mode;
+    int generatedVerticesCount = 0;
     int verticesCount = count;
     if (count > 4) {
         // Polyline: account for extra vertices needed for continous tri-strip
         verticesCount += (count -4);
     }
+
+    getAlphaAndMode(paint, &alpha, &mode);
+    setupDraw();
+    if (isAA) {
+        setupDrawAALine();
+    }
+    setupDrawColor(paint->getColor(), alpha);
+    setupDrawColorFilter();
+    setupDrawShader();
+    if (isAA) {
+        setupDrawBlending(true, mode);
+    } else {
+        setupDrawBlending(mode);
+    }
+    setupDrawProgram();
+    setupDrawModelViewIdentity(true);
+    setupDrawColorUniforms();
+    setupDrawColorFilterUniforms();
+    setupDrawShaderIdentityUniforms();
+
+    if (isHairLine) {
+        // Set a real stroke width to be used in quad construction
+        strokeWidth = .5;
+    }
     if (isAA) {
         // Expand boundary to enable AA calculations on the quad border
         strokeWidth += .5f;
@@ -1407,25 +1440,22 @@
     if (!isAA) {
         setupDrawVertices(vertices);
     } else {
-        AlphaVertex* alphaCoords = aaVertices + gVertexAlphaOffset;
+        void* alphaCoords = ((GLbyte*) aaVertices) + gVertexAlphaOffset;
         // innerProportion is the ratio of the inner (non-AA) port of the line to the total
         // AA stroke width (the base stroke width expanded by a half pixel on either side).
         // This value is used in the fragment shader to determine how to fill fragments.
         float innerProportion = fmax(strokeWidth - 1.0f, 0) / (strokeWidth + .5f);
-        setupDrawAALine((void*) aaVertices, (void*) alphaCoords, innerProportion);
+        setupDrawAALine((void*) aaVertices, alphaCoords, innerProportion);
     }
 
-    int generatedVerticesCount = 0;
     AlphaVertex *prevAAVertex = NULL;
     Vertex *prevVertex = NULL;
     float inverseScaleX = 1.0f;
     float inverseScaleY = 1.0f;
 
-    if (isHairline) {
+    if (isHairLine) {
         // The quad that we use for AA hairlines needs to account for scaling because the line
         // should always be one pixel wide regardless of scale.
-        inverseScaleX = 1.0f;
-        inverseScaleY = 1.0f;
         if (!mSnapshot->transform->isPureTranslate()) {
             Matrix4 *mat = mSnapshot->transform;
             float m00 = mat->data[Matrix4::kScaleX];
@@ -1446,22 +1476,19 @@
         vec2 a(points[i], points[i + 1]);
         vec2 b(points[i + 2], points[i + 3]);
 
-        // Bias to snap to the same pixels as Skia
-        a += 0.375;
-        b += 0.375;
-
         // Find the normal to the line
         vec2 n = (b - a).copyNormalized() * strokeWidth;
-        if (isHairline) {
-            float wideningFactor;
-            if (fabs(n.x) >= fabs(n.y)) {
-                wideningFactor = fabs(1.0f / n.x);
-            } else {
-                wideningFactor = fabs(1.0f / n.y);
+        if (isHairLine) {
+            n *= inverseScaleX;
+            if (isAA) {
+                float wideningFactor;
+                if (fabs(n.x) >= fabs(n.y)) {
+                    wideningFactor = fabs(1.0f / n.x);
+                } else {
+                    wideningFactor = fabs(1.0f / n.y);
+                }
+                n *= wideningFactor;
             }
-            n.x *= inverseScaleX;
-            n.y *= inverseScaleY;
-            n *= wideningFactor;
         }
         float x = n.x;
         n.x = -n.y;
@@ -1525,69 +1552,6 @@
     }
 }
 
-void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return;
-
-    const bool isAA = paint->isAntiAlias();
-    const float strokeWidth = paint->getStrokeWidth() * 0.5f;
-    // A stroke width of 0 has a special meaning in Skia:
-    // it draws a line 1 px wide regardless of current transform
-    bool isHairLine = paint->getStrokeWidth() == 0.0f;
-
-    int alpha;
-    SkXfermode::Mode mode;
-    getAlphaAndMode(paint, &alpha, &mode);
-    int generatedVerticesCount = 0;
-
-    setupDraw();
-    if (isAA) {
-        setupDrawAALine();
-    }
-    setupDrawColor(paint->getColor(), alpha);
-    setupDrawColorFilter();
-    setupDrawShader();
-    if (isAA) {
-        setupDrawBlending(true, mode);
-    } else {
-        setupDrawBlending(mode);
-    }
-    setupDrawProgram();
-    setupDrawModelViewIdentity();
-    setupDrawColorUniforms();
-    setupDrawColorFilterUniforms();
-    setupDrawShaderIdentityUniforms();
-
-    if (!isHairLine) {
-        drawLinesAsQuads(points, count, isAA, isHairLine, strokeWidth);
-    } else {
-        if (isAA) {
-            drawLinesAsQuads(points, count, isAA, isHairLine, .5f);
-        } else {
-            int verticesCount = count >> 1;
-            Vertex lines[verticesCount];
-            Vertex* vertices = &lines[0];
-            setupDrawVertices(vertices);
-            for (int i = 0; i < count; i += 4) {
-
-                const float left = fmin(points[i], points[i + 2]);
-                const float right = fmax(points[i], points[i + 2]);
-                const float top = fmin(points[i + 1], points[i + 3]);
-                const float bottom = fmax(points[i + 1], points[i + 3]);
-
-                Vertex::set(vertices++, points[i], points[i + 1]);
-                Vertex::set(vertices++, points[i + 2], points[i + 3]);
-                generatedVerticesCount += 2;
-                dirtyLayer(left, top,
-                        right == left ? left + 1 : right, bottom == top ? top + 1 : bottom,
-                        *mSnapshot->transform);
-            }
-
-            glLineWidth(1.0f);
-            glDrawArrays(GL_LINES, 0, generatedVerticesCount);
-        }
-    }
-}
-
 void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
     if (mSnapshot->isIgnored()) return;
 
@@ -1596,8 +1560,13 @@
 
     // A stroke width of 0 has a special meaning in Skia:
     // it draws an unscaled 1px point
+    float strokeWidth = paint->getStrokeWidth();
     const bool isHairLine = paint->getStrokeWidth() == 0.0f;
-
+    if (isHairLine) {
+        // Now that we know it's hairline, we can set the effective width, to be used later
+        strokeWidth = 1.0f;
+    }
+    const float halfWidth = strokeWidth / 2;
     int alpha;
     SkXfermode::Mode mode;
     getAlphaAndMode(paint, &alpha, &mode);
@@ -1609,13 +1578,13 @@
     TextureVertex* vertex = &pointsData[0];
 
     setupDraw();
-    setupDrawPoint(isHairLine ? 1.0f : paint->getStrokeWidth());
+    setupDrawPoint(strokeWidth);
     setupDrawColor(paint->getColor(), alpha);
     setupDrawColorFilter();
     setupDrawShader();
     setupDrawBlending(mode);
     setupDrawProgram();
-    setupDrawModelViewIdentity();
+    setupDrawModelViewIdentity(true);
     setupDrawColorUniforms();
     setupDrawColorFilterUniforms();
     setupDrawPointUniforms();
@@ -1625,6 +1594,11 @@
     for (int i = 0; i < count; i += 2) {
         TextureVertex::set(vertex++, points[i], points[i + 1], 0.0f, 0.0f);
         generatedVerticesCount++;
+        float left = points[i] - halfWidth;
+        float right = points[i] + halfWidth;
+        float top = points[i + 1] - halfWidth;
+        float bottom = points [i + 1] + halfWidth;
+        dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
     }
 
     glDrawArrays(GL_POINTS, 0, generatedVerticesCount);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 0276095..918e1fb 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -283,19 +283,6 @@
     void drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint);
 
     /**
-     * Draws a line as a quad. Called by drawLines() for all cases except hairline without AA.
-     *
-     * @param points The vertices of the lines. Every four entries specifies the x/y points
-     * of a single line segment.
-     * @param count The number of entries in the points array.
-     * @param isAA Whether the line is anti-aliased
-     * @param isHairline Whether the line has strokeWidth==0, which results in the line being
-     * one pixel wide on the display regardless of scale.
-     */
-    void drawLinesAsQuads(float *points, int count, bool isAA, bool isHairline,
-            float strokeWidth);
-
-    /**
      * Draws a textured rectangle with the specified texture. The specified coordinates
      * are transformed by the current snapshot's transform matrix.
      *
@@ -453,7 +440,7 @@
             bool swapSrcDst = false);
     void setupDrawProgram();
     void setupDrawDirtyRegionsDisabled();
-    void setupDrawModelViewIdentity();
+    void setupDrawModelViewIdentity(bool offset = false);
     void setupDrawModelView(float left, float top, float right, float bottom,
             bool ignoreTransform = false, bool ignoreModelView = false);
     void setupDrawModelViewTranslate(float left, float top, float right, float bottom,
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 2187f24..972dd87 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -124,8 +124,15 @@
 }
 
 void Program::set(const mat4& projectionMatrix, const mat4& modelViewMatrix,
-        const mat4& transformMatrix) {
+        const mat4& transformMatrix, bool offset) {
     mat4 t(projectionMatrix);
+    if (offset) {
+        // offset screenspace xy by an amount that compensates for typical precision issues
+        // in GPU hardware that tends to paint hor/vert lines in pixels shifted up and to the left.
+        // This offset value is based on an assumption that some hardware may use as little
+        // as 12.4 precision, so we offset by slightly more than 1/16.
+        t.translate(.375, .375, 0);
+    }
     t.multiply(transformMatrix);
     t.multiply(modelViewMatrix);
 
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index afc6f3d..764cb05 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -81,7 +81,7 @@
      * transform matrices.
      */
     void set(const mat4& projectionMatrix, const mat4& modelViewMatrix,
-             const mat4& transformMatrix);
+             const mat4& transformMatrix, bool offset = false);
 
     /**
      * Sets the color associated with this shader.
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index cb6d7e0..f4e3f57 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -26,20 +26,6 @@
 
 #include "RenderScriptDefines.h"
 
-RsDevice rsDeviceCreate();
-void rsDeviceDestroy(RsDevice);
-void rsDeviceSetConfig(RsDevice, RsDeviceParam, int32_t value);
-
-RsContext rsContextCreate(RsDevice, uint32_t version);
-RsContext rsContextCreateGL(RsDevice, uint32_t version,
-                            RsSurfaceConfig sc, uint32_t dpi);
-void rsContextDestroy(RsContext);
-
-RsMessageToClientType rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen, bool wait);
-RsMessageToClientType rsContextPeekMessage(RsContext vrsc, size_t *receiveLen, uint32_t *subID, bool wait);
-void rsContextInitToClient(RsContext);
-void rsContextDeinitToClient(RsContext);
-
 //
 // A3D loading and object update code.
 // Should only be called at object creation, not thread safe
@@ -63,18 +49,8 @@
 void rsaElementGetNativeData(RsContext, RsElement, uint32_t *elemData, uint32_t elemDataSize);
 void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char **names, uint32_t dataSize);
 
-// Async commands for returning new IDS
-RsType rsaTypeCreate(RsContext, RsElement, uint32_t dimX, uint32_t dimY,
-                     uint32_t dimZ, bool mips, bool faces);
-RsAllocation rsaAllocationCreateTyped(RsContext rsc, RsType vtype,
-                                      RsAllocationMipmapControl mips,
-                                      uint32_t usages);
-RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
-                                           RsAllocationMipmapControl mips,
-                                           const void *data, uint32_t usages);
-RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
-                                               RsAllocationMipmapControl mips,
-                                               const void *data, uint32_t usages);
+
+
 #ifdef ANDROID_RS_SERIALIZE
 #define NO_RS_FUNCS
 #endif
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index dac5cec..998296b 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -1,4 +1,110 @@
 
+DeviceCreate {
+    direct
+    nocontext
+    ret RsDevice
+}
+
+DeviceDestroy {
+    direct
+    nocontext
+    param RsDevice dev
+}
+
+DeviceSetConfig {
+    direct
+    nocontext
+    param RsDevice dev
+    param RsDeviceParam p
+    param int32_t value
+}
+
+ContextCreate {
+    direct
+    nocontext
+    param RsDevice dev
+    param uint32_t version
+    ret RsContext
+}
+
+ContextCreateGL {
+    direct
+    nocontext
+    param RsDevice dev
+    param uint32_t version
+    param RsSurfaceConfig sc
+    param uint32_t dpi
+    ret RsContext
+}
+
+ContextDestroy {
+    direct
+}
+
+ContextGetMessage {
+    direct
+    param void *data
+    param size_t *receiveLen
+    param uint32_t *subID
+    param bool wait
+    ret RsMessageToClientType
+}
+
+ContextPeekMessage {
+    direct
+    param size_t *receiveLen
+    param uint32_t *subID
+    param bool wait
+    ret RsMessageToClientType
+}
+
+ContextInitToClient {
+    direct
+}
+
+ContextDeinitToClient {
+    direct
+}
+
+aTypeCreate {
+    direct
+    param RsElement e
+    param uint32_t dimX
+    param uint32_t dimY
+    param uint32_t dimZ
+    param bool mips
+    param bool faces
+    ret RsType
+}
+
+aAllocationCreateTyped {
+    direct
+    param RsType vtype
+    param RsAllocationMipmapControl mips
+    param uint32_t usages
+    ret RsAllocation
+}
+
+aAllocationCreateFromBitmap {
+    direct
+    param RsType vtype
+    param RsAllocationMipmapControl mips
+    param const void *data
+    param uint32_t usages
+    ret RsAllocation
+}
+
+aAllocationCubeCreateFromBitmap {
+    direct
+    param RsType vtype
+    param RsAllocationMipmapControl mips
+    param const void *data
+    param uint32_t usages
+    ret RsAllocation
+}
+
+
+
 ContextFinish {
 	handcodeApi
 	}
@@ -82,23 +188,21 @@
 
 
 Allocation1DData {
+	handcodeApi
 	param RsAllocation va
 	param uint32_t xoff
 	param uint32_t lod
 	param uint32_t count
 	param const void *data
-	handcodeApi
-	togglePlay
 	}
 
 Allocation1DElementData {
+	handcodeApi
 	param RsAllocation va
 	param uint32_t x
 	param uint32_t lod
 	param const void *data
 	param uint32_t comp_offset
-	handcodeApi
-	togglePlay
 	}
 
 Allocation2DData {
@@ -186,11 +290,10 @@
 	}
 
 ScriptInvokeV {
+	handcodeApi
 	param RsScript s
 	param uint32_t slot
 	param const void * data
-	handcodeApi
-	togglePlay
 	}
 
 ScriptSetVarI {
@@ -224,11 +327,10 @@
 	}
 
 ScriptSetVarV {
+	handcodeApi
 	param RsScript s
 	param uint32_t slot
 	param const void * data
-	handcodeApi
-	togglePlay
 	}
 
 
@@ -330,3 +432,4 @@
 MeshInitVertexAttribs {
 	param RsMesh mesh
 	}
+
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index a759004..743b2c4 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -833,7 +833,7 @@
 
 RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
                                            RsAllocationMipmapControl mips,
-                                           const void *data, uint32_t usages) {
+                                           const void *data, size_t data_length, uint32_t usages) {
     Context *rsc = static_cast<Context *>(con);
     Type *t = static_cast<Type *>(vtype);
 
@@ -855,7 +855,7 @@
 
 RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
                                                RsAllocationMipmapControl mips,
-                                               const void *data, uint32_t usages) {
+                                               const void *data, size_t data_length, uint32_t usages) {
     Context *rsc = static_cast<Context *>(con);
     Type *t = static_cast<Type *>(vtype);
 
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 0ca892d..50f5f55 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -768,14 +768,20 @@
     return rsc;
 }
 
-RsMessageToClientType rsContextPeekMessage(RsContext vrsc, size_t *receiveLen, uint32_t *subID, bool wait) {
+RsMessageToClientType rsContextPeekMessage(RsContext vrsc,
+                                           size_t * receiveLen, size_t receiveLen_length,
+                                           uint32_t * subID, size_t subID_length, bool wait) {
     Context * rsc = static_cast<Context *>(vrsc);
     return rsc->peekMessageToClient(receiveLen, subID, wait);
 }
 
-RsMessageToClientType rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen, bool wait) {
+RsMessageToClientType rsContextGetMessage(RsContext vrsc, void * data, size_t data_length,
+                                          size_t * receiveLen, size_t receiveLen_length,
+                                          uint32_t * subID, size_t subID_length, bool wait) {
     Context * rsc = static_cast<Context *>(vrsc);
-    return rsc->getMessageToClient(data, receiveLen, subID, bufferLen, wait);
+    rsAssert(subID_length == sizeof(uint32_t));
+    rsAssert(receiveLen_length == sizeof(size_t));
+    return rsc->getMessageToClient(data, receiveLen, subID, data_length, wait);
 }
 
 void rsContextInitToClient(RsContext vrsc) {
diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c
index 4ac5b7f..14b380a 100644
--- a/libs/rs/rsg_generator.c
+++ b/libs/rs/rsg_generator.c
@@ -4,7 +4,7 @@
 
 void printFileHeader(FILE *f) {
     fprintf(f, "/*\n");
-    fprintf(f, " * Copyright (C) 2010 The Android Open Source Project\n");
+    fprintf(f, " * Copyright (C) 2011 The Android Open Source Project\n");
     fprintf(f, " *\n");
     fprintf(f, " * Licensed under the Apache License, Version 2.0 (the \"License\");\n");
     fprintf(f, " * you may not use this file except in compliance with the License.\n");
@@ -96,12 +96,14 @@
 void printFuncDecl(FILE *f, const ApiEntry *api, const char *prefix, int addContext) {
     printVarType(f, &api->ret);
     fprintf(f, " %s%s (", prefix, api->name);
-    if (addContext) {
-        fprintf(f, "Context *");
-    } else {
-        fprintf(f, "RsContext rsc");
+    if (!api->nocontext) {
+        if (addContext) {
+            fprintf(f, "Context *");
+        } else {
+            fprintf(f, "RsContext rsc");
+        }
     }
-    printArgList(f, api, 1);
+    printArgList(f, api, !api->nocontext);
     fprintf(f, ")");
 }
 
@@ -117,6 +119,10 @@
 void printPlaybackFuncs(FILE *f, const char *prefix) {
     int ct;
     for (ct=0; ct < apiCount; ct++) {
+        if (apis[ct].direct) {
+            continue;
+        }
+
         fprintf(f, "void %s%s (Context *, const void *);\n", prefix, apis[ct].name);
     }
 }
@@ -140,6 +146,10 @@
         int needFlush = 0;
         const ApiEntry * api = &apis[ct];
 
+        if (api->direct) {
+            continue;
+        }
+
         printFuncDecl(f, api, "rs", 0);
         fprintf(f, "\n{\n");
         if (api->handcodeApi) {
@@ -198,31 +208,37 @@
     for (ct=0; ct < apiCount; ct++) {
         const ApiEntry * api = &apis[ct];
 
+        if (api->direct) {
+            continue;
+        }
+
         fprintf(f, "void rsp_%s(Context *con, const void *vp)\n", api->name);
         fprintf(f, "{\n");
-        if (api->handcodePlay) {
-            fprintf(f, "    rsHCPLAY_%s(con, vp);\n", api->name);
-        } else {
-            //fprintf(f, "    LOGE(\"play command %s\\n\");\n", api->name);
-            fprintf(f, "    const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name);
-            fprintf(f, "    ");
-            if (api->ret.typeName[0]) {
-                fprintf(f, "con->mIO.mToCoreRet = (intptr_t)");
-            }
-            fprintf(f, "rsi_%s(con", api->name);
-            for (ct2=0; ct2 < api->paramCount; ct2++) {
-                const VarType *vt = &api->params[ct2];
-                fprintf(f, ",\n           cmd->%s", vt->name);
-            }
-            fprintf(f, ");\n");
+
+        //fprintf(f, "    LOGE(\"play command %s\\n\");\n", api->name);
+        fprintf(f, "    const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name);
+        fprintf(f, "    ");
+        if (api->ret.typeName[0]) {
+            fprintf(f, "con->mIO.mToCoreRet = (intptr_t)");
         }
+        fprintf(f, "rsi_%s(con", api->name);
+        for (ct2=0; ct2 < api->paramCount; ct2++) {
+            const VarType *vt = &api->params[ct2];
+            fprintf(f, ",\n           cmd->%s", vt->name);
+        }
+        fprintf(f, ");\n");
+
         fprintf(f, "};\n\n");
     }
 
     fprintf(f, "RsPlaybackFunc gPlaybackFuncs[%i] = {\n", apiCount + 1);
     fprintf(f, "    NULL,\n");
     for (ct=0; ct < apiCount; ct++) {
-        fprintf(f, "    %s%s,\n", "rsp_", apis[ct].name);
+        if (apis[ct].direct) {
+            fprintf(f, "    NULL,\n");
+        } else {
+            fprintf(f, "    %s%s,\n", "rsp_", apis[ct].name);
+        }
     }
     fprintf(f, "};\n");
 
diff --git a/libs/rs/spec.h b/libs/rs/spec.h
index 82650a7..ecc5cc7 100644
--- a/libs/rs/spec.h
+++ b/libs/rs/spec.h
@@ -25,7 +25,8 @@
   char name[256];
   int sync;
   int handcodeApi;
-  int handcodePlay;
+  int direct;
+  int nocontext;
   int paramCount;
   VarType ret;
   VarType params[16];
diff --git a/libs/rs/spec.l b/libs/rs/spec.l
index c8af891..dcd4435 100644
--- a/libs/rs/spec.l
+++ b/libs/rs/spec.l
@@ -44,6 +44,7 @@
 <comment>"*"+"/"        BEGIN(INITIAL);
 
 <*>" "   //printf("found ' '\n");
+<*>"\t"   //printf("found ' '\n");
 <*>"\n"  ++num_lines; //printf("found lf \n");
 
 {ID} {
@@ -64,8 +65,12 @@
     apis[apiCount].handcodeApi = 1;
     }
 
-<api_entry2>"handcodePlay" {
-    apis[apiCount].handcodePlay = 1;
+<api_entry2>"direct" {
+    apis[apiCount].direct = 1;
+    }
+
+<api_entry2>"nocontext" {
+    apis[apiCount].nocontext = 1;
     }
 
 <api_entry2>"ret" {
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index 08db902..ef4d3d0 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -453,6 +453,10 @@
     }
 
     if (left == mNumSampleSizes) {
+        if (flags == kFlagAfter) {
+            return ERROR_OUT_OF_RANGE;
+        }
+
         --left;
     }
 
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index 4f28855..54c0d77 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -487,14 +487,12 @@
         { "audio/3gpp",
           "file:///sdcard/media_api/video/H263_500_AMRNB_12.3gp" },
         { "audio/amr-wb",
-          "file:///sdcard/media_api/music_perf/AMRWB/"
-          "NIN_AMR-WB_15.85kbps_16kbps.amr" },
+          "file:///sdcard/media_api/music/"
+          "AI_AMR-WB_12.65kbps(13kbps)_16khz_mono_NMC.awb" },
         { "audio/mp4a-latm",
-          "file:///sdcard/media_api/music_perf/AAC/"
-          "WC_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4" },
+          "file:///sdcard/media_api/video/H264_AAC.3gp" },
         { "audio/mpeg",
-          "file:///sdcard/media_api/music_perf/MP3/"
-          "WC_256kbps_44.1khz_mono_CBR_DPA.mp3" }
+          "file:///sdcard/media_api/music/MP3CBR.mp3" }
     };
 
     for (size_t i = 0; i < sizeof(kMimeToURL) / sizeof(kMimeToURL[0]); ++i) {
@@ -626,8 +624,10 @@
                      requestedSeekTimeUs, requestedSeekTimeUs / 1E6);
             }
 
-            MediaBuffer *buffer;
-            options.setSeekTo(requestedSeekTimeUs);
+            MediaBuffer *buffer = NULL;
+            options.setSeekTo(
+                    requestedSeekTimeUs, MediaSource::ReadOptions::SEEK_NEXT_SYNC);
+
             if (seekSource->read(&buffer, &options) != OK) {
                 CHECK_EQ(buffer, NULL);
                 actualSeekTimeUs = -1;
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 1ad8047..d96369b 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -642,14 +642,16 @@
     }
 
     /**
-     * Installs or removes the accessibility input filter when accessibility is enabled
-     * or disabled.
+     * Sets the input filter state. If the filter is in enabled it is registered
+     * in the window manager, otherwise the filter is removed from the latter.
+     *
+     * @param enabled Whether the input filter is enabled.
      */
-    private void updateInputFilterLocked() {
+    private void setInputFilterEnabledLocked(boolean enabled) {
         WindowManagerService wm = (WindowManagerService)ServiceManager.getService(
                 Context.WINDOW_SERVICE);
         if (wm != null) {
-            if (mIsEnabled) {
+            if (enabled) {
                 if (mInputFilter == null) {
                     mInputFilter = new AccessibilityInputFilter(mContext);
                 }
@@ -681,7 +683,7 @@
         if (enabledServices.size() > 0
                 && service.mFeedbackType == AccessibilityServiceInfo.FEEDBACK_SPOKEN) {
             updateClientsLocked();
-            updateInputFilterLocked();
+            setInputFilterEnabledLocked(true);
         }
     }
 
@@ -697,7 +699,7 @@
         if (enabledServices.isEmpty()
                 && service.mFeedbackType == AccessibilityServiceInfo.FEEDBACK_SPOKEN) {
             updateClientsLocked();
-            updateInputFilterLocked();
+            setInputFilterEnabledLocked(false);
         }
     }
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c4027e0..b2f95cd 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -986,8 +986,16 @@
     ssize_t index = mActiveBufferIndex;
     if (index >= 0) {
         if (!mFailover) {
-            Image& texture(mBufferData[index].texture);
-            err = mTextureManager.initEglImage(&texture, dpy, buffer);
+            {
+               // Without that lock, there is a chance of race condition
+               // where while composing a specific index, requestBuf
+               // with the same index can be executed and touch the same data
+               // that is being used in initEglImage.
+               // (e.g. dirty flag in texture)
+               Mutex::Autolock _l(mLock);
+               Image& texture(mBufferData[index].texture);
+               err = mTextureManager.initEglImage(&texture, dpy, buffer);
+            }
             // if EGLImage fails, we switch to regular texture mode, and we
             // free all resources associated with using EGLImages.
             if (err == NO_ERROR) {
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index c763b1d..31b2ddd 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -406,6 +406,15 @@
         </activity>
 
         <activity
+                android:name="PointsActivity"
+                android:label="_Points">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity
                 android:name="Transform3dActivity"
                 android:label="_3d">
             <intent-filter>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/Lines2Activity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/Lines2Activity.java
index ccf0631..55fab3f 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/Lines2Activity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/Lines2Activity.java
@@ -42,8 +42,9 @@
         swView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
         frame.addView(swView);
         final LinesView hwBothView = new LinesView(this, 850, Color.GREEN);
-        // BUG: some lines not drawn or drawn with alpha when enabling hw layers
-//        hwBothView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        // Don't actually need to render to a hw layer, but it's a good sanity-check that
+        // we're rendering to/from layers correctly
+        hwBothView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
         frame.addView(hwBothView);
         final LinesView swBothView = new LinesView(this, 854, Color.RED);
         swBothView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PointsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PointsActivity.java
new file mode 100644
index 0000000..b3fb7a1
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PointsActivity.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.hwui;
+
+import android.animation.ObjectAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.SeekBar;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class PointsActivity extends Activity {
+
+    float mSeekValue = .5f;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getWindow().setBackgroundDrawable(new ColorDrawable(0xff000000));
+        SeekBar slider = new SeekBar(this);
+        LinearLayout container = new LinearLayout(this);
+        container.setOrientation(LinearLayout.VERTICAL);
+        setContentView(container);
+
+        container.addView(slider);
+        slider.setMax(100);
+        slider.setProgress(50);
+        FrameLayout frame = new FrameLayout(this);
+        final RenderingView gpuView = new RenderingView(this, Color.GREEN);
+        frame.addView(gpuView);
+        final RenderingView swView = new RenderingView(this, Color.RED);
+        swView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+        frame.addView(swView);
+        container.addView(frame);
+
+        slider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                mSeekValue = (float)progress / 100.0f;
+                float gpuAlpha = Math.min(2.0f * mSeekValue, 1f);
+                gpuView.setAlpha(gpuAlpha);
+                float swAlpha = Math.min((1 - mSeekValue) * 2.0f, 1f);
+                System.out.println("(gpuAlpha, swAlpha = " + gpuAlpha + ", " + swAlpha);
+                swView.setAlpha(swAlpha);
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+        });
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+    }
+
+    public static class RenderingView extends View {
+
+        private int mColor;
+
+        public RenderingView(Context c, int color) {
+            super(c);
+            mColor = color;
+        }
+
+        private void drawPoints(Canvas canvas, Paint p, float xOffset, float yOffset) {
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+            Paint p = new Paint();
+            p.setColor(mColor);
+
+            float yOffset = 0;
+            for (int i = 0; i < 2; ++i) {
+                float xOffset = 0;
+
+                p.setStrokeWidth(0f);
+                p.setStrokeCap(Paint.Cap.SQUARE);
+                canvas.drawPoint(100 + xOffset, 100 + yOffset, p);
+                xOffset += 5;
+
+                p.setStrokeWidth(1f);
+                canvas.drawPoint(100 + xOffset, 100 + yOffset, p);
+                xOffset += 15;
+
+                p.setStrokeWidth(20);
+                canvas.drawPoint(100 + xOffset, 100 + yOffset, p);
+                xOffset += 30;
+
+                p.setStrokeCap(Paint.Cap.ROUND);
+                canvas.drawPoint(100 + xOffset, 100 + yOffset, p);
+
+                p.setAntiAlias(true);
+                yOffset += 30;
+            }
+
+        }
+    }
+}
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 7462701..e776463 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -88,9 +88,8 @@
                 }
 
                 // This is a hack to work around an invalidation bug
-                mBitmapOut = Bitmap.createBitmap(mBitmapOut);
+                mBitmapOut.setPixel(0, 0, 0);
                 mOutPixelsAllocation.copyTo(mBitmapOut);
-                mDisplayView.setImageBitmap(mBitmapOut);
                 mDisplayView.invalidate();
             }
         };