Don't clear the framebuffer when not needed.
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index f0b00dd..2fadb82 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -135,10 +135,10 @@
 
     @Override
     void onPreDraw() {
-        nPrepare(mRenderer);
+        nPrepare(mRenderer, mOpaque);
     }
 
-    private native void nPrepare(int renderer);
+    private native void nPrepare(int renderer, boolean opaque);
 
     @Override
     void onPostDraw() {
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 2cc4052..b87dbc5 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -585,7 +585,7 @@
 
         @Override
         GLES20Canvas createCanvas() {
-            return mGlCanvas = new GLES20Canvas(true);
+            return mGlCanvas = new GLES20Canvas(mTranslucent);
         }
 
         @Override
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 155122f..79f1f5b 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -16,25 +16,41 @@
 
 package android.view;
 
-import com.android.internal.view.BaseSurfaceHolder;
-import com.android.internal.view.IInputMethodCallback;
-import com.android.internal.view.IInputMethodSession;
-import com.android.internal.view.RootViewSurfaceTaker;
-
+import android.Manifest;
+import android.app.ActivityManagerNative;
+import android.content.ClipDescription;
+import android.content.ComponentCallbacks;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
 import android.graphics.Point;
 import android.graphics.PointF;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.Region;
-import android.os.*;
+import android.media.AudioManager;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.LatencyTimer;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
 import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.util.AndroidRuntimeException;
 import android.util.Config;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.util.EventLog;
+import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.View.MeasureSpec;
@@ -43,21 +59,14 @@
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.Scroller;
-import android.content.pm.PackageManager;
-import android.content.res.CompatibilityInfo;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.ClipData;
-import android.content.ClipDescription;
-import android.content.ComponentCallbacks;
-import android.content.Context;
-import android.app.ActivityManagerNative;
-import android.Manifest;
-import android.media.AudioManager;
+import com.android.internal.view.BaseSurfaceHolder;
+import com.android.internal.view.IInputMethodCallback;
+import com.android.internal.view.IInputMethodSession;
+import com.android.internal.view.RootViewSurfaceTaker;
 
-import java.lang.ref.WeakReference;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
 /**
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 7521af4..2001919 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -103,8 +103,8 @@
 }
 
 static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject canvas,
-        OpenGLRenderer* renderer) {
-    renderer->prepare();
+        OpenGLRenderer* renderer, jboolean opaque) {
+    renderer->prepare(opaque);
 }
 
 static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject canvas,
@@ -445,7 +445,7 @@
     { "nCreateRenderer",    "()I",             (void*) android_view_GLES20Canvas_createRenderer },
     { "nDestroyRenderer",   "(I)V",            (void*) android_view_GLES20Canvas_destroyRenderer },
     { "nSetViewport",       "(III)V",          (void*) android_view_GLES20Canvas_setViewport },
-    { "nPrepare",           "(I)V",            (void*) android_view_GLES20Canvas_prepare },
+    { "nPrepare",           "(IZ)V",           (void*) android_view_GLES20Canvas_prepare },
     { "nFinish",            "(I)V",            (void*) android_view_GLES20Canvas_finish },
     { "nAcquireContext",    "(I)V",            (void*) android_view_GLES20Canvas_acquireContext },
     { "nReleaseContext",    "(I)V",            (void*) android_view_GLES20Canvas_releaseContext },
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index ce85d46..61e5408 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -342,7 +342,7 @@
     mHeight = height;
 }
 
-void DisplayListRenderer::prepare() {
+void DisplayListRenderer::prepare(bool opaque) {
     mSnapshot = new Snapshot(mFirstSnapshot,
             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
     mSaveCount = 1;
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 5d02bd7..0fbfce1 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -209,7 +209,7 @@
     ~DisplayListRenderer();
 
     void setViewport(int width, int height);
-    void prepare();
+    void prepare(bool opaque);
 
     void acquireContext();
     void releaseContext();
diff --git a/libs/hwui/OpenGLDebugRenderer.cpp b/libs/hwui/OpenGLDebugRenderer.cpp
index 4e5123e..b9583e5 100644
--- a/libs/hwui/OpenGLDebugRenderer.cpp
+++ b/libs/hwui/OpenGLDebugRenderer.cpp
@@ -23,10 +23,10 @@
 namespace android {
 namespace uirenderer {
 
-void OpenGLDebugRenderer::prepare() {
+void OpenGLDebugRenderer::prepare(bool opaque) {
     mPrimitivesCount = 0;
     LOGD("========= Frame start =========");
-    OpenGLRenderer::prepare();
+    OpenGLRenderer::prepare(opaque);
 }
 
 void OpenGLDebugRenderer::finish() {
diff --git a/libs/hwui/OpenGLDebugRenderer.h b/libs/hwui/OpenGLDebugRenderer.h
index ce15512..2ac19ae 100644
--- a/libs/hwui/OpenGLDebugRenderer.h
+++ b/libs/hwui/OpenGLDebugRenderer.h
@@ -34,7 +34,7 @@
     ~OpenGLDebugRenderer() {
     }
 
-    void prepare();
+    void prepare(bool opaque);
     void finish();
 
     int saveLayer(float left, float top, float right, float bottom,
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index ee5fe22..5399668 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -150,7 +150,7 @@
     mFirstSnapshot->viewport.set(0, 0, width, height);
 }
 
-void OpenGLRenderer::prepare() {
+void OpenGLRenderer::prepare(bool opaque) {
     mSnapshot = new Snapshot(mFirstSnapshot,
             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
     mSaveCount = 1;
@@ -160,8 +160,10 @@
     glDisable(GL_DITHER);
     glDisable(GL_SCISSOR_TEST);
 
-    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-    glClear(GL_COLOR_BUFFER_BIT);
+    if (!opaque) {
+        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+        glClear(GL_COLOR_BUFFER_BIT);
+    }
 
     glEnable(GL_SCISSOR_TEST);
     glScissor(0, 0, mWidth, mHeight);
@@ -325,7 +327,10 @@
  *   - Issue the drawing
  *
  * Switching rendering target n + 1 times per drawn primitive is extremely costly.
- * To avoid this, layers are implemented in a different way here.
+ * To avoid this, layers are implemented in a different way here, at least in the
+ * general case. FBOs are used, as an optimization, when the "clip to layer" flag
+ * is set. When this flag is set we can redirect all drawing operations into a
+ * single FBO.
  *
  * This implementation relies on the frame buffer being at least RGBA 8888. When
  * a layer is created, only a texture is created, not an FBO. The content of the
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e3d4653..4caa8fb 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -67,7 +67,7 @@
 
     virtual void setViewport(int width, int height);
 
-    virtual void prepare();
+    virtual void prepare(bool opaque);
     virtual void finish();
 
     virtual void acquireContext();