Correct implementation of saveLayer().

Change-Id: I5375126636913e0a84f2d6bbd0ebe40d2e4f2763
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 833fa70..b5987c3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16,9 +16,6 @@
 
 package android.view;
 
-import com.android.internal.R;
-import com.android.internal.view.menu.MenuBuilder;
-
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -49,8 +46,6 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.util.AttributeSet;
-import android.util.Config;
-import android.util.EventLog;
 import android.util.Log;
 import android.util.Pool;
 import android.util.Poolable;
@@ -67,6 +62,8 @@
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.ScrollBarDrawable;
+import com.android.internal.R;
+import com.android.internal.view.menu.MenuBuilder;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -4022,12 +4019,13 @@
      */
     public boolean dispatchKeyEvent(KeyEvent event) {
         // If any attached key listener a first crack at the event.
-        //noinspection SimplifiableIfStatement
 
+        //noinspection SimplifiableIfStatement,deprecation
         if (android.util.Config.LOGV) {
             captureViewInfo("captureViewKeyEvent", this);
         }
 
+        //noinspection SimplifiableIfStatement
         if (mOnKeyListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
                 && mOnKeyListener.onKey(this, event.getKeyCode(), event)) {
             return true;
@@ -4059,6 +4057,7 @@
             return false;
         }
 
+        //noinspection SimplifiableIfStatement
         if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
                 mOnTouchListener.onTouch(this, event)) {
             return true;
@@ -4075,6 +4074,7 @@
      * @see #getFilterTouchesWhenObscured
      */
     public boolean onFilterTouchEventForSecurity(MotionEvent event) {
+        //noinspection RedundantIfStatement
         if ((mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0
                 && (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0) {
             // Window is obscured, drop this touch.
@@ -7829,8 +7829,7 @@
         saveCount = canvas.getSaveCount();
 
         int solidColor = getSolidColor();
-        // TODO: Temporarily disable fading edges with hardware acceleration
-        if (solidColor == 0 && !canvas.isHardwareAccelerated()) {
+        if (solidColor == 0) {
             final int flags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
 
             if (drawTop) {
@@ -9577,6 +9576,7 @@
         if (mAttachInfo == null) {
             return false;
         }
+        //noinspection SimplifiableIfStatement
         if ((flags & HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING) == 0
                 && !isHapticFeedbackEnabled()) {
             return false;
diff --git a/core/res/res/drawable-xlarge/default_wallpaper.jpg b/core/res/res/drawable-xlarge/default_wallpaper.jpg
index afb0acc..5acad94 100644
--- a/core/res/res/drawable-xlarge/default_wallpaper.jpg
+++ b/core/res/res/drawable-xlarge/default_wallpaper.jpg
Binary files differ
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index d4db782..c527038 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -63,28 +63,19 @@
  */
 struct Layer {
     /**
-     * Coordinates of the layer corresponding to this snapshot.
-     * Only set when the flag kFlagIsLayer is set.
+     * Coordinates of the layer.
      */
     Rect layer;
     /**
      * Name of the texture used to render the layer.
-     * Only set when the flag kFlagIsLayer is set.
      */
     GLuint texture;
     /**
-     * Name of the FBO used to render the layer.
-     * Only set when the flag kFlagIsLayer is set.
-     */
-    GLuint fbo;
-    /**
      * Opacity of the layer.
-     * Only set when the flag kFlagIsLayer is set.
      */
-    float alpha;
+    int alpha;
     /**
      * Blending mode of the layer.
-     * Only set when the flag kFlagIsLayer is set.
      */
     SkXfermode::Mode mode;
     /**
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index a204778..1a18766 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -87,7 +87,6 @@
     if (layer) {
         mSize -= layer->layer.getWidth() * layer->layer.getHeight() * 4;
 
-        glDeleteFramebuffers(1, &layer->fbo);
         glDeleteTextures(1, &layer->texture);
         delete layer;
     }
@@ -99,7 +98,7 @@
     mCache.setOnEntryRemovedListener(NULL);
 }
 
-Layer* LayerCache::get(LayerSize& size, GLuint previousFbo) {
+Layer* LayerCache::get(LayerSize& size) {
     Layer* layer = mCache.remove(size);
     if (layer) {
         LAYER_LOGD("Reusing layer");
@@ -111,10 +110,6 @@
         layer = new Layer;
         layer->blend = true;
 
-        // Generate the FBO and attach the texture
-        glGenFramebuffers(1, &layer->fbo);
-        glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo);
-
         // Generate the texture in which the FBO will draw
         glGenTextures(1, &layer->texture);
         glBindTexture(GL_TEXTURE_2D, layer->texture);
@@ -128,23 +123,6 @@
 
         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width, size.height, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
-        // Bind texture to FBO
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-                layer->texture, 0);
-
-        GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-        if (status != GL_FRAMEBUFFER_COMPLETE) {
-            LOGE("Framebuffer incomplete (GL error code 0x%x)", status);
-
-            glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
-
-            glDeleteFramebuffers(1, &layer->fbo);
-            glDeleteTextures(1, &layer->texture);
-            delete layer;
-
-            return NULL;
-        }
     }
 
     return layer;
diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h
index 9860994..c0c7542 100644
--- a/libs/hwui/LayerCache.h
+++ b/libs/hwui/LayerCache.h
@@ -62,10 +62,8 @@
      * size of the cache goes down.
      *
      * @param size The dimensions of the desired layer
-     * @param previousFbo The name of the FBO to bind to if creating a new
-     *        layer fails
      */
-    Layer* get(LayerSize& size, GLuint previousFbo);
+    Layer* get(LayerSize& size);
     /**
      * Adds the layer to the cache. The layer will not be added if there is
      * not enough space available.
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 6c90704..7cf70f7 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -80,6 +80,21 @@
         { SkXfermode::kXor_Mode,     GL_ONE_MINUS_DST_ALPHA,  GL_ONE_MINUS_SRC_ALPHA }
 };
 
+static const Blender gBlendsSwap[] = {
+        { SkXfermode::kClear_Mode,   GL_ZERO,                 GL_ZERO },
+        { SkXfermode::kSrc_Mode,     GL_ZERO,                 GL_ONE },
+        { SkXfermode::kDst_Mode,     GL_ONE,                  GL_ZERO },
+        { SkXfermode::kSrcOver_Mode, GL_ONE_MINUS_DST_ALPHA,  GL_ONE },
+        { SkXfermode::kDstOver_Mode, GL_ONE,                  GL_ONE_MINUS_SRC_ALPHA },
+        { SkXfermode::kSrcIn_Mode,   GL_ZERO,                 GL_SRC_ALPHA },
+        { SkXfermode::kDstIn_Mode,   GL_DST_ALPHA,            GL_ZERO },
+        { SkXfermode::kSrcOut_Mode,  GL_ZERO,                 GL_ONE_MINUS_SRC_ALPHA },
+        { SkXfermode::kDstOut_Mode,  GL_ONE_MINUS_DST_ALPHA,  GL_ZERO },
+        { SkXfermode::kSrcATop_Mode, GL_ONE_MINUS_DST_ALPHA,  GL_SRC_ALPHA },
+        { SkXfermode::kDstATop_Mode, GL_DST_ALPHA,            GL_ONE_MINUS_SRC_ALPHA },
+        { SkXfermode::kXor_Mode,     GL_ONE_MINUS_DST_ALPHA,  GL_ONE_MINUS_SRC_ALPHA }
+};
+
 static const GLenum gTextureUnits[] = {
         GL_TEXTURE0,
         GL_TEXTURE1,
@@ -122,8 +137,6 @@
 
     mWidth = width;
     mHeight = height;
-    mFirstSnapshot->height = height;
-    mFirstSnapshot->viewport.set(0, 0, width, height);
 }
 
 void OpenGLRenderer::prepare() {
@@ -155,14 +168,19 @@
 }
 
 void OpenGLRenderer::releaseContext() {
-    glViewport(0, 0, mSnapshot->viewport.getWidth(), mSnapshot->viewport.getHeight());
+    glViewport(0, 0, mWidth, mHeight);
 
     glEnable(GL_SCISSOR_TEST);
     setScissorFromClip();
 
+    glDisable(GL_DITHER);
+
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
     if (mCaches.blend) {
         glEnable(GL_BLEND);
         glBlendFunc(mCaches.lastSrcMode, mCaches.lastDstMode);
+        glBlendEquation(GL_FUNC_ADD);
     } else {
         glDisable(GL_BLEND);
     }
@@ -202,17 +220,10 @@
 bool OpenGLRenderer::restoreSnapshot() {
     bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet;
     bool restoreLayer = mSnapshot->flags & Snapshot::kFlagIsLayer;
-    bool restoreOrtho = mSnapshot->flags & Snapshot::kFlagDirtyOrtho;
 
     sp<Snapshot> current = mSnapshot;
     sp<Snapshot> previous = mSnapshot->previous;
 
-    if (restoreOrtho) {
-        Rect& r = previous->viewport;
-        glViewport(r.left, r.top, r.right, r.bottom);
-        mOrthoMatrix.load(current->orthoMatrix);
-    }
-
     mSaveCount--;
     mSnapshot = previous;
 
@@ -253,11 +264,7 @@
         mode = SkXfermode::kSrcOver_Mode;
     }
 
-    if (alpha > 0 && !mSnapshot->invisible) {
-        createLayer(mSnapshot, left, top, right, bottom, alpha, mode, flags);
-    } else {
-        mSnapshot->invisible = true;
-    }
+    createLayer(mSnapshot, left, top, right, bottom, alpha, mode, flags);
 
     return count;
 }
@@ -278,49 +285,42 @@
     LAYER_LOGD("Requesting layer %fx%f", right - left, bottom - top);
     LAYER_LOGD("Layer cache size = %d", mCaches.layerCache.getSize());
 
+    // Window coordinates of the layer
     Rect bounds(left, top, right, bottom);
-    // TODO: Apply transformations and treat layers in screen coordinates
-    // mSnapshot->transform->mapRect(bounds);
+    mSnapshot->transform->mapRect(bounds);
 
-    GLuint previousFbo = snapshot->previous.get() ? snapshot->previous->fbo : 0;
     LayerSize size(bounds.getWidth(), bounds.getHeight());
 
-    Layer* layer = mCaches.layerCache.get(size, previousFbo);
+    Layer* layer = mCaches.layerCache.get(size);
     if (!layer) {
         return false;
     }
 
-    glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo);
-
-    // Clear the FBO
-    glDisable(GL_SCISSOR_TEST);
-    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-    glClear(GL_COLOR_BUFFER_BIT);
-    glEnable(GL_SCISSOR_TEST);
-
     layer->mode = mode;
-    layer->alpha = alpha / 255.0f;
+    layer->alpha = alpha;
     layer->layer.set(bounds);
 
     // Save the layer in the snapshot
     snapshot->flags |= Snapshot::kFlagIsLayer;
     snapshot->layer = layer;
-    snapshot->fbo = layer->fbo;
-    // TODO: Temporary until real layer support is implemented
-    snapshot->resetTransform(-bounds.left, -bounds.top, 0.0f);
-    // TODO: Temporary until real layer support is implemented
-    snapshot->resetClip(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
-    snapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
-    snapshot->height = bounds.getHeight();
-    snapshot->flags |= Snapshot::kFlagDirtyOrtho;
-    snapshot->orthoMatrix.load(mOrthoMatrix);
 
+    // Copy the framebuffer into the layer
+    glBindTexture(GL_TEXTURE_2D, layer->texture);
+    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left, mHeight - bounds.bottom,
+            bounds.getWidth(), bounds.getHeight(), 0);
+
+    // Clear the framebuffer where the layer will draw
+    glScissor(bounds.left, mHeight - bounds.bottom, bounds.getWidth(), bounds.getHeight());
+    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    if (flags & SkCanvas::kClipToLayer_SaveFlag) {
+        mSnapshot->clipTransformed(bounds);
+    }
+
+    // Restore the initial clip
     setScissorFromClip();
 
-    // Change the ortho projection
-    glViewport(0, 0, bounds.getWidth(), bounds.getHeight());
-    mOrthoMatrix.loadOrtho(0.0f, bounds.getWidth(), bounds.getHeight(), 0.0f, -1.0f, 1.0f);
-
     return true;
 }
 
@@ -330,22 +330,32 @@
         return;
     }
 
-    // Unbind current FBO and restore previous one
-    // Most of the time, previous->fbo will be 0 to bind the default buffer
-    glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
-
     // Restore the clip from the previous snapshot
     const Rect& clip = *previous->clipRect;
-    glScissor(clip.left, previous->height - clip.bottom, clip.getWidth(), clip.getHeight());
+    glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight());
 
     Layer* layer = current->layer;
     const Rect& rect = layer->layer;
 
-    // FBOs are already drawn with a top-left origin, don't flip the texture
+    if (layer->alpha < 255) {
+        glEnable(GL_BLEND);
+        glBlendFuncSeparate(GL_ZERO, GL_SRC_ALPHA, GL_DST_ALPHA, GL_ZERO);
+
+        drawColorRect(rect.left, rect.top, rect.right, rect.bottom,
+                layer->alpha << 24, SkXfermode::kSrcOver_Mode, true, true);
+
+        glBlendFunc(mCaches.lastSrcMode, mCaches.lastDstMode);
+        if (!mCaches.blend) {
+            glDisable(GL_BLEND);
+        }
+    }
+
+    // Layers are already drawn with a top-left origin, don't flip the texture
     resetDrawTextureTexCoords(0.0f, 1.0f, 1.0f, 0.0f);
 
-    drawTextureRect(rect.left, rect.top, rect.right, rect.bottom,
-            layer->texture, layer->alpha, layer->mode, layer->blend);
+    drawTextureMesh(rect.left, rect.top, rect.right, rect.bottom, layer->texture,
+            1.0f, layer->mode, layer->blend, &mMeshVertices[0].position[0],
+            &mMeshVertices[0].texture[0], NULL, 0, true, true);
 
     resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
 
@@ -355,7 +365,6 @@
     if (!mCaches.layerCache.put(size, layer)) {
         LAYER_LOGD("Deleting layer");
 
-        glDeleteFramebuffers(1, &layer->fbo);
         glDeleteTextures(1, &layer->texture);
 
         delete layer;
@@ -397,7 +406,7 @@
 
 void OpenGLRenderer::setScissorFromClip() {
     const Rect& clip = *mSnapshot->clipRect;
-    glScissor(clip.left, mSnapshot->height - clip.bottom, clip.getWidth(), clip.getHeight());
+    glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight());
 }
 
 const Rect& OpenGLRenderer::getClipBounds() {
@@ -405,8 +414,6 @@
 }
 
 bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
-    if (mSnapshot->invisible) return true;
-
     Rect r(left, top, right, bottom);
     mSnapshot->transform->mapRect(r);
     return !mSnapshot->clipRect->intersects(r);
@@ -512,7 +519,6 @@
 }
 
 void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
-    if (mSnapshot->invisible) return;
     const Rect& clip = *mSnapshot->clipRect;
     drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
 }
@@ -545,10 +551,10 @@
 
 void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
         float x, float y, SkPaint* paint) {
-    if (mSnapshot->invisible || text == NULL || count == 0 ||
-            (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
+    if (text == NULL || count == 0 || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
         return;
     }
+    paint->setAntiAlias(true);
 
     float scaleX = paint->getTextScaleX();
     bool applyScaleX = scaleX < 0.9999f || scaleX > 1.0001f;
@@ -619,8 +625,6 @@
 }
 
 void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
-    if (mSnapshot->invisible) return;
-
     GLuint textureUnit = 0;
     glActiveTexture(gTextureUnits[textureUnit]);
 
@@ -778,6 +782,7 @@
      }
 }
 
+// Same values used by Skia
 #define kStdStrikeThru_Offset   (-6.0f / 21.0f)
 #define kStdUnderline_Offset    (1.0f / 9.0f)
 #define kStdUnderline_Thickness (1.0f / 18.0f)
@@ -830,7 +835,7 @@
 }
 
 void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom,
-        int color, SkXfermode::Mode mode, bool ignoreTransform) {
+        int color, SkXfermode::Mode mode, bool ignoreTransform, bool ignoreBlending) {
     // If a shader is set, preserve only the alpha
     if (mShader) {
         color |= 0x00ffffff;
@@ -854,8 +859,10 @@
         mColorFilter->describe(description, mExtensions);
     }
 
-    // Setup the blending mode
-    chooseBlending(alpha < 255 || (mShader && mShader->blend()), mode, description);
+    if (!ignoreBlending) {
+        // Setup the blending mode
+        chooseBlending(alpha < 255 || (mShader && mShader->blend()), mode, description);
+    }
 
     // Build and use the appropriate shader
     useProgram(mCaches.programCache.get(description));
@@ -905,7 +912,8 @@
 
 void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float bottom,
         GLuint texture, float alpha, SkXfermode::Mode mode, bool blend,
-        GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount) {
+        GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount,
+        bool swapSrcDst, bool ignoreTransform) {
     ProgramDescription description;
     description.hasTexture = true;
     if (mColorFilter) {
@@ -915,10 +923,15 @@
     mModelView.loadTranslate(left, top, 0.0f);
     mModelView.scale(right - left, bottom - top, 1.0f);
 
-    chooseBlending(blend || alpha < 1.0f, mode, description);
+    chooseBlending(blend || alpha < 1.0f, mode, description, swapSrcDst);
 
     useProgram(mCaches.programCache.get(description));
-    mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
+    if (!ignoreTransform) {
+        mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
+    } else {
+        mat4 m;
+        mCaches.currentProgram->set(mOrthoMatrix, mModelView, m);
+    }
 
     // Texture
     bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, 0);
@@ -948,7 +961,7 @@
 }
 
 void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode,
-        ProgramDescription& description) {
+        ProgramDescription& description, bool swapSrcDst) {
     blend = blend || mode != SkXfermode::kSrcOver_Mode;
     if (blend) {
         if (mode < SkXfermode::kPlus_Mode) {
@@ -956,8 +969,8 @@
                 glEnable(GL_BLEND);
             }
 
-            GLenum sourceMode = gBlends[mode].src;
-            GLenum destMode = gBlends[mode].dst;
+            GLenum sourceMode = swapSrcDst ? gBlendsSwap[mode].src : gBlends[mode].src;
+            GLenum destMode = swapSrcDst ? gBlendsSwap[mode].dst : gBlends[mode].dst;
 
             if (sourceMode != mCaches.lastSrcMode || destMode != mCaches.lastDstMode) {
                 glBlendFunc(sourceMode, destMode);
@@ -970,6 +983,7 @@
             // the blending, turn blending off here
             if (mExtensions.hasFramebufferFetch()) {
                 description.framebufferMode = mode;
+                description.swapSrcDst = swapSrcDst;
             }
 
             if (mCaches.blend) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 50f42c2..e7f933f 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -166,9 +166,11 @@
      * @param color The rectangle's ARGB color, defined as a packed 32 bits word
      * @param mode The Skia xfermode to use
      * @param ignoreTransform True if the current transform should be ignored
+     * @paran ignoreBlending True if the blending is set by the caller
      */
     void drawColorRect(float left, float top, float right, float bottom,
-    		int color, SkXfermode::Mode mode, bool ignoreTransform = false);
+    		int color, SkXfermode::Mode mode, bool ignoreTransform = false,
+    		bool ignoreBlending = false);
 
     /**
      * Draws a textured rectangle with the specified texture. The specified coordinates
@@ -216,10 +218,13 @@
      * @param texCoords The texture coordinates of each vertex
      * @param indices The indices of the vertices, can be NULL
      * @param elementsCount The number of elements in the mesh, required by indices
+     * @param swapSrcDst Whether or not the src and dst blending operations should be swapped
+     * @param ignoreTransform True if the current transform should be ignored
      */
     void drawTextureMesh(float left, float top, float right, float bottom, GLuint texture,
             float alpha, SkXfermode::Mode mode, bool blend,
-            GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount = 0);
+            GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount = 0,
+            bool swapSrcDst = false, bool ignoreTransform = false);
 
     /**
      * Prepares the renderer to draw the specified shadow.
@@ -322,8 +327,13 @@
      * Enable or disable blending as necessary. This function sets the appropriate
      * blend function based on the specified xfermode.
      */
-    inline void chooseBlending(bool blend, SkXfermode::Mode mode, ProgramDescription& description);
+    inline void chooseBlending(bool blend, SkXfermode::Mode mode, ProgramDescription& description,
+            bool swapSrcDst = false);
 
+    /**
+     * Safely retrieves the mode from the specified xfermode. If the specified
+     * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode.
+     */
     inline SkXfermode::Mode getXfermode(SkXfermode* mode);
 
     /**
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index ff65c1b..becbc22 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -119,6 +119,8 @@
         "    gl_FragColor = fragColor;\n";
 const char* gFS_Main_FragColor_Blend =
         "    gl_FragColor = blendFramebuffer(fragColor, gl_LastFragColor);\n";
+const char* gFS_Main_FragColor_Blend_Swap =
+        "    gl_FragColor = blendFramebuffer(gl_LastFragColor, fragColor);\n";
 const char* gFS_Main_ApplyColorOp[4] = {
         // None
         "",
@@ -376,7 +378,8 @@
         if (!blendFramebuffer) {
             shader.append(gFS_Main_FragColor);
         } else {
-            shader.append(gFS_Main_FragColor_Blend);
+            shader.append(!description.swapSrcDst ?
+                    gFS_Main_FragColor_Blend : gFS_Main_FragColor_Blend_Swap);
         }
     }
     // End the shader
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index 8f5304d..0a17052 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -35,7 +35,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 // Debug
-#define DEBUG_PROGRAM_CACHE 1
+#define DEBUG_PROGRAM_CACHE 0
 
 // Debug
 #if DEBUG_PROGRAM_CACHE
@@ -44,6 +44,9 @@
     #define PROGRAM_LOGD(...)
 #endif
 
+/*
+ * IMPORTANT: All 32 bits are used, switch to a long.
+ */
 #define PROGRAM_KEY_TEXTURE 0x1
 #define PROGRAM_KEY_A8_TEXTURE 0x2
 #define PROGRAM_KEY_BITMAP 0x4
@@ -53,6 +56,7 @@
 #define PROGRAM_KEY_COLOR_LIGHTING 0x40
 #define PROGRAM_KEY_COLOR_BLEND 0x80
 #define PROGRAM_KEY_BITMAP_NPOT 0x100
+#define PROGRAM_KEY_SWAP_SRC_DST 0x2000
 
 #define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600
 #define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800
@@ -70,6 +74,9 @@
 // Types
 ///////////////////////////////////////////////////////////////////////////////
 
+/*
+ * IMPORTANT: All 32 bits are used, switch to a long.
+ */
 typedef uint32_t programid;
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -95,7 +102,7 @@
         shadersMode(SkXfermode::kClear_Mode), isBitmapFirst(false),
         bitmapWrapS(GL_CLAMP_TO_EDGE), bitmapWrapT(GL_CLAMP_TO_EDGE),
         colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode),
-        framebufferMode(SkXfermode::kClear_Mode) {
+        framebufferMode(SkXfermode::kClear_Mode), swapSrcDst(false) {
     }
 
     // Texturing
@@ -118,6 +125,7 @@
     // Framebuffer blending (requires Extensions.hasFramebufferFetch())
     // Ignored for all values < SkXfermode::kPlus_Mode
     SkXfermode::Mode framebufferMode;
+    bool swapSrcDst;
 
     inline uint32_t getEnumForWrap(GLenum wrap) const {
         switch (wrap) {
@@ -163,6 +171,7 @@
                 break;
         }
         key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
+        if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
         return key;
     }
 }; // struct ProgramDescription
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index da48243..ebedf53 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -43,7 +43,7 @@
  */
 class Snapshot: public LightRefBase<Snapshot> {
 public:
-    Snapshot(): invisible(false), flags(0), previous(NULL), layer(NULL), fbo(0) {
+    Snapshot(): flags(0), previous(NULL), layer(NULL) {
         transform = &mTransformRoot;
         clipRect = &mClipRectRoot;
     }
@@ -53,13 +53,7 @@
      * the previous snapshot.
      */
     Snapshot(const sp<Snapshot>& s, int saveFlags):
-            height(s->height),
-            invisible(s->invisible),
-            flags(0),
-            previous(s),
-            layer(NULL),
-            fbo(s->fbo),
-            viewport(s->viewport) {
+            flags(0), previous(s), layer(NULL) {
         if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
             mTransformRoot.load(*s->transform);
             transform = &mTransformRoot;
@@ -97,23 +91,30 @@
          */
         kFlagIsLayer = 0x2,
         /**
-         * Indicates that this snapshot has changed the ortho matrix.
-         */
-        kFlagDirtyOrtho = 0x4,
-        /**
          * Indicates that the local clip should be recomputed.
          */
-        kFlagDirtyLocalClip = 0x8,
+        kFlagDirtyLocalClip = 0x4,
     };
 
     /**
-     * Intersects the current clip with the new clip rectangle.
+     * Modifies the current clip with the new clip rectangle and
+     * the specified operation. The specified rectangle is transformed
+     * by this snapshot's trasnformation.
      */
-    bool clip(float left, float top, float right, float bottom, SkRegion::Op op) {
-        bool clipped = false;
-
+    bool clip(float left, float top, float right, float bottom,
+            SkRegion::Op op = SkRegion::kIntersect_Op) {
         Rect r(left, top, right, bottom);
         transform->mapRect(r);
+        return clipTransformed(r, op);
+    }
+
+    /**
+     * Modifies the current clip with the new clip rectangle and
+     * the specified operation. The specified rectangle is considered
+     * already transformed.
+     */
+    bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op) {
+        bool clipped = false;
 
         switch (op) {
             case SkRegion::kDifference_Op:
@@ -162,29 +163,6 @@
         return mLocalClip;
     }
 
-    // TODO: Temporary
-    void resetTransform(float x, float y, float z) {
-        transform = &mTransformRoot;
-        transform->loadTranslate(x, y, z);
-    }
-
-    // TODO: Temporary
-    void resetClip(float left, float top, float right, float bottom) {
-        clipRect = &mClipRectRoot;
-        clipRect->set(left, top, right, bottom);
-        flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
-    }
-
-    /**
-     * Height of the framebuffer the snapshot is rendering into.
-     */
-    int height;
-
-    /**
-     * If true, the layer won't be rendered.
-     */
-    bool invisible;
-
     /**
      * Dirty flags.
      */
@@ -199,17 +177,6 @@
      * Only set when the flag kFlagIsLayer is set.
      */
     Layer* layer;
-    GLuint fbo;
-
-    /**
-     * Current viewport.
-     */
-    Rect viewport;
-
-    /**
-     * Contains the previous ortho matrix.
-     */
-    mat4 orthoMatrix;
 
     /**
      * Local transformation. Holds the current translation, scale and
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index ec1cbf1..d30a723 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.google.android.test.hwui">
+    package="com.android.test.hwui">
 
     <application
         android:label="HwUi"
@@ -71,6 +71,15 @@
         </activity>
 
         <activity
+                android:name="NewLayersActivity"
+                android:label="_NewLayers">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        
+        <activity
                 android:name="XfermodeActivity"
                 android:label="_Xfermodes"
                 android:theme="@android:style/Theme.Translucent.NoTitleBar">
@@ -164,6 +173,15 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+
+        <activity
+                android:name="TransparentListActivity"
+                android:label="_TransparentList">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
         
         <activity
                 android:name="MoreShadersActivity"
diff --git a/tests/HwAccelerationTest/res/drawable/default_wallpaper.jpg b/tests/HwAccelerationTest/res/drawable/default_wallpaper.jpg
new file mode 100644
index 0000000..5acad94
--- /dev/null
+++ b/tests/HwAccelerationTest/res/drawable/default_wallpaper.jpg
Binary files differ
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/AdvancedBlendActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/AdvancedBlendActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/AdvancedBlendActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/AdvancedBlendActivity.java
index 6c80a6d..5baa20c 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/AdvancedBlendActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/AdvancedBlendActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/AlphaLayersActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/AlphaLayersActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/AlphaLayersActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/AlphaLayersActivity.java
index 0217a05..1a68a93 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/AlphaLayersActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/AlphaLayersActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapsActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/BitmapsActivity.java
index cfa8d3c..40543530 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapsActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsAlphaActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapsAlphaActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsAlphaActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/BitmapsAlphaActivity.java
index f6fd8fe..ef49c7f 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsAlphaActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapsAlphaActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsRectActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapsRectActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsRectActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/BitmapsRectActivity.java
index f8726c2..b192209 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsRectActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapsRectActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/ColorFiltersActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/ColorFiltersActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersActivity.java
index 49e1eaa..09d63d6 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/ColorFiltersActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/FramebufferBlendActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/FramebufferBlendActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/FramebufferBlendActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/FramebufferBlendActivity.java
index ef84b67..1556bae 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/FramebufferBlendActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/FramebufferBlendActivity.java
@@ -15,7 +15,7 @@
  */
 
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/LayersActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/LayersActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/LayersActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/LayersActivity.java
index 437cd1c..b705117 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/LayersActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/LayersActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/LinesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/LinesActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
index c800d42..208dd88 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/LinesActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/ListActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
similarity index 99%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/ListActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
index 94b936b..8fd4f6b 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/ListActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/MoreShadersActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MoreShadersActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/MoreShadersActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/MoreShadersActivity.java
index f43eeba..182a474 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/MoreShadersActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MoreShadersActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/NewLayersActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/NewLayersActivity.java
new file mode 100644
index 0000000..5b7753e
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/NewLayersActivity.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.os.Bundle;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class NewLayersActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new LayersView(this));
+    }
+
+    static class LayersView extends View {
+        private Paint mLayerPaint;
+        private final Paint mRectPaint;
+
+        LayersView(Context c) {
+            super(c);
+
+            mLayerPaint = new Paint();
+            mRectPaint = new Paint();
+            mRectPaint.setAntiAlias(true);
+            mRectPaint.setTextSize(24.0f);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+            
+            canvas.drawRGB(128, 255, 128);
+            canvas.translate(140.0f, 100.0f);
+            
+            mLayerPaint.setAlpha(127);
+            int count = canvas.saveLayer(0.0f, 0.0f, 200.0f, 100.0f, mLayerPaint,
+                    Canvas.ALL_SAVE_FLAG);
+
+            mRectPaint.setColor(0x7fff0000);
+            canvas.drawRect(-20.0f, -20.0f, 220.0f, 120.0f, mRectPaint);
+
+            mRectPaint.setColor(0xff000000);
+            canvas.drawText("This is a very long string to overlap between layers and framebuffer",
+                    -100.0f, 50.0f, mRectPaint);
+            
+            canvas.restoreToCount(count);
+
+            canvas.translate(0.0f, 200.0f);
+            
+            mLayerPaint.setAlpha(127);
+            count = canvas.saveLayer(0.0f, 0.0f, 200.0f, 100.0f, mLayerPaint,
+                    Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
+
+            mRectPaint.setColor(0x7fff0000);
+            canvas.drawRect(-20.0f, -20.0f, 220.0f, 120.0f, mRectPaint);
+
+            mRectPaint.setColor(0xff000000);
+            canvas.drawText("This is a very long string to overlap between layers and framebuffer",
+                    -100.0f, 50.0f, mRectPaint);
+            
+            canvas.restoreToCount(count);
+        }
+    }
+}
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/NinePatchesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/NinePatchesActivity.java
similarity index 97%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/NinePatchesActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/NinePatchesActivity.java
index 3268fbf..7410f79 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/NinePatchesActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/NinePatchesActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/PathsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsActivity.java
similarity index 99%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/PathsActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/PathsActivity.java
index 39d9942..8d9bf37 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/PathsActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/QuickRejectActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/QuickRejectActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/QuickRejectActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/QuickRejectActivity.java
index 2ba249a..5192bfe 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/QuickRejectActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/QuickRejectActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/ResizeActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ResizeActivity.java
similarity index 95%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/ResizeActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/ResizeActivity.java
index e5771b8..04f9de1 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/ResizeActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ResizeActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/RotationActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/RotationActivity.java
similarity index 97%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/RotationActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/RotationActivity.java
index e629cb8..5c309b4 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/RotationActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/RotationActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/ShadersActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/ShadersActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java
index 0cd1426..9c8e7ec 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/ShadersActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/SimplePathsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/SimplePathsActivity.java
similarity index 97%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/SimplePathsActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/SimplePathsActivity.java
index 071a118..c3e18a3 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/SimplePathsActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/SimplePathsActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/StackActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/StackActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/StackActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/StackActivity.java
index 5c8db6e..5655adf 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/StackActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/StackActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.graphics.drawable.Drawable;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/TextActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/TextActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java
index abe9d5e..eb0df51 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/TextActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/TextGammaActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextGammaActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/TextGammaActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/TextGammaActivity.java
index 185cfa4..773d390 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/TextGammaActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextGammaActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/Transform3dActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/Transform3dActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/Transform3dActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/Transform3dActivity.java
index 6134cde..6df66e6 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/Transform3dActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/Transform3dActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/ListActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TransparentListActivity.java
similarity index 96%
copy from tests/HwAccelerationTest/src/com/google/android/test/hwui/ListActivity.java
copy to tests/HwAccelerationTest/src/com/android/test/hwui/TransparentListActivity.java
index 94b936b..83d16a5 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/ListActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TransparentListActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;
@@ -30,7 +30,7 @@
 import android.widget.TextView;
 
 @SuppressWarnings({"UnusedDeclaration"})
-public class ListActivity extends Activity {
+public class TransparentListActivity extends Activity {
     private static final String[] DATA_LIST = {
             "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
             "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
@@ -78,12 +78,15 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        
+        getWindow().setBackgroundDrawable(getResources().getDrawable(R.drawable.default_wallpaper));
         setContentView(R.layout.list_activity);
 
         ListAdapter adapter = new SimpleListAdapter(this);
 
         ListView list = (ListView) findViewById(R.id.list);
         list.setAdapter(adapter);
+        list.setCacheColorHint(0);
         
         registerForContextMenu(list);
     }
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/XfermodeActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/XfermodeActivity.java
similarity index 98%
rename from tests/HwAccelerationTest/src/com/google/android/test/hwui/XfermodeActivity.java
rename to tests/HwAccelerationTest/src/com/android/test/hwui/XfermodeActivity.java
index 8c81f02..411077f 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/XfermodeActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/XfermodeActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.test.hwui;
+package com.android.test.hwui;
 
 import android.app.Activity;
 import android.content.Context;