Merge "Update the EGL_ANDROID_fence_sync spec."
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 4f32146..6f4be09 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -66,16 +66,11 @@
         eMatrixChanged              = 0x00000010,
         eTransparentRegionChanged   = 0x00000020,
         eVisibilityChanged          = 0x00000040,
-        eFreezeTintChanged          = 0x00000080,
         eCropChanged                = 0x00000100,
     };
 
     enum {
         eLayerHidden        = 0x01,
-        eLayerFrozen        = 0x02,
-        eLayerDither        = 0x04,
-        eLayerFilter        = 0x08,
-        eLayerBlurFreeze    = 0x10
     };
 
     enum {
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 50bdf71..7b8873a 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -65,13 +65,10 @@
     status_t    setSize(uint32_t w, uint32_t h);
     status_t    hide();
     status_t    show(int32_t layer = -1);
-    status_t    freeze();
-    status_t    unfreeze();
     status_t    setFlags(uint32_t flags, uint32_t mask);
     status_t    setTransparentRegionHint(const Region& transparent);
     status_t    setAlpha(float alpha=1.0f);
     status_t    setMatrix(float dsdx, float dtdx, float dsdy, float dtdy);
-    status_t    setFreezeTint(uint32_t tint);
     status_t    setCrop(const Rect& crop);
 
     static status_t writeSurfaceToParcel(
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 3bd10de..9f3ef35 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -93,12 +93,6 @@
         
     //! Close a composer transaction on all active SurfaceComposerClients.
     static void closeGlobalTransaction(bool synchronous = false);
-    
-    //! Freeze the specified display but not transactions.
-    static status_t freezeDisplay(DisplayID dpy, uint32_t flags = 0);
-        
-    //! Resume updates on the specified display.
-    static status_t unfreezeDisplay(DisplayID dpy, uint32_t flags = 0);
 
     //! Set the orientation of the given display
     static int setOrientation(DisplayID dpy, int orientation, uint32_t flags);
@@ -117,13 +111,10 @@
 
     status_t    hide(SurfaceID id);
     status_t    show(SurfaceID id, int32_t layer = -1);
-    status_t    freeze(SurfaceID id);
-    status_t    unfreeze(SurfaceID id);
     status_t    setFlags(SurfaceID id, uint32_t flags, uint32_t mask);
     status_t    setTransparentRegionHint(SurfaceID id, const Region& transparent);
     status_t    setLayer(SurfaceID id, int32_t layer);
     status_t    setAlpha(SurfaceID id, float alpha=1.0f);
-    status_t    setFreezeTint(SurfaceID id, uint32_t tint);
     status_t    setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy);
     status_t    setPosition(SurfaceID id, float x, float y);
     status_t    setSize(SurfaceID id, uint32_t w, uint32_t h);
diff --git a/include/media/hardware/CryptoAPI.h b/include/media/hardware/CryptoAPI.h
index 810a443..44a0040 100644
--- a/include/media/hardware/CryptoAPI.h
+++ b/include/media/hardware/CryptoAPI.h
@@ -70,7 +70,9 @@
     // At the java level these special errors will then trigger a
     // MediaCodec.CryptoException that gives clients access to both
     // the error code and the errorDetailMsg.
-    virtual status_t decrypt(
+    // Returns a non-negative result to indicate the number of bytes written
+    // to the dstPtr, or a negative result to indicate an error.
+    virtual ssize_t decrypt(
             bool secure,
             const uint8_t key[16],
             const uint8_t iv[16],
diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index 9151c11..239dd87 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -36,7 +36,7 @@
     layer_state_t()
         :   surface(0), what(0),
             x(0), y(0), z(0), w(0), h(0),
-            alpha(0), tint(0), flags(0), mask(0),
+            alpha(0), flags(0), mask(0),
             reserved(0)
     {
         matrix.dsdx = matrix.dtdy = 1.0f;
@@ -61,7 +61,6 @@
             uint32_t        w;
             uint32_t        h;
             float           alpha;
-            uint32_t        tint;
             uint8_t         flags;
             uint8_t         mask;
             uint8_t         reserved;
diff --git a/include/utils/SystemClock.h b/include/utils/SystemClock.h
index 7c319be..d75264c 100644
--- a/include/utils/SystemClock.h
+++ b/include/utils/SystemClock.h
@@ -25,6 +25,7 @@
 int setCurrentTimeMillis(int64_t millis);
 int64_t uptimeMillis();
 int64_t elapsedRealtime();
+int64_t elapsedRealtimeNano();
 
 }; // namespace android
 
diff --git a/include/utils/Timers.h b/include/utils/Timers.h
index 8b4d322..92f66c9 100644
--- a/include/utils/Timers.h
+++ b/include/utils/Timers.h
@@ -78,9 +78,10 @@
     SYSTEM_TIME_REALTIME = 0,  // system-wide realtime clock
     SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point
     SYSTEM_TIME_PROCESS = 2,   // high-resolution per-process clock
-    SYSTEM_TIME_THREAD = 3     // high-resolution per-thread clock
+    SYSTEM_TIME_THREAD = 3,    // high-resolution per-thread clock
+    SYSTEM_TIME_BOOTTIME = 4   // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time
 };
-    
+
 // return the system-time according to the specified clock
 #ifdef __cplusplus
 nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC);
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index d7590f0..b9cbfa6 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -122,18 +122,6 @@
     const sp<SurfaceComposerClient>& client(mClient);
     return client->show(mToken, layer);
 }
-status_t SurfaceControl::freeze() {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->freeze(mToken);
-}
-status_t SurfaceControl::unfreeze() {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->unfreeze(mToken);
-}
 status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
     status_t err = validate();
     if (err < 0) return err;
@@ -158,12 +146,6 @@
     const sp<SurfaceComposerClient>& client(mClient);
     return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
 }
-status_t SurfaceControl::setFreezeTint(uint32_t tint) {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->setFreezeTint(mToken, tint);
-}
 status_t SurfaceControl::setCrop(const Rect& crop) {
     status_t err = validate();
     if (err < 0) return err;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 8fa2167..b1bd78b 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -121,9 +121,6 @@
             float alpha);
     status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id,
             float dsdx, float dtdx, float dsdy, float dtdy);
-    status_t setFreezeTint(
-            const sp<SurfaceComposerClient>& client, SurfaceID id,
-            uint32_t tint);
     status_t setOrientation(int orientation);
     status_t setCrop(const sp<SurfaceComposerClient>& client, SurfaceID id,
             const Rect& crop);
@@ -271,17 +268,6 @@
     return NO_ERROR;
 }
 
-status_t Composer::setFreezeTint(const sp<SurfaceComposerClient>& client,
-        SurfaceID id, uint32_t tint) {
-    Mutex::Autolock _l(mLock);
-    layer_state_t* s = getLayerStateLocked(client, id);
-    if (!s)
-        return BAD_INDEX;
-    s->what |= ISurfaceComposer::eFreezeTintChanged;
-    s->tint = tint;
-    return NO_ERROR;
-}
-
 status_t Composer::setOrientation(int orientation) {
     Mutex::Autolock _l(mLock);
     mOrientation = orientation;
@@ -415,10 +401,6 @@
     return getComposer().setCrop(this, id, crop);
 }
 
-status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) {
-    return getComposer().setFreezeTint(this, id, tint);
-}
-
 status_t SurfaceComposerClient::setPosition(SurfaceID id, float x, float y) {
     return getComposer().setPosition(this, id, x, y);
 }
@@ -443,18 +425,6 @@
             ISurfaceComposer::eLayerHidden);
 }
 
-status_t SurfaceComposerClient::freeze(SurfaceID id) {
-    return getComposer().setFlags(this, id,
-            ISurfaceComposer::eLayerFrozen,
-            ISurfaceComposer::eLayerFrozen);
-}
-
-status_t SurfaceComposerClient::unfreeze(SurfaceID id) {
-    return getComposer().setFlags(this, id,
-            0,
-            ISurfaceComposer::eLayerFrozen);
-}
-
 status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags,
         uint32_t mask) {
     return getComposer().setFlags(this, id, flags, mask);
@@ -542,20 +512,6 @@
 
 // ----------------------------------------------------------------------------
 
-status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
-{
-    // This has been made a no-op because it can cause Gralloc buffer deadlocks.
-    return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
-{
-    // This has been made a no-op because it can cause Gralloc buffer deadlocks.
-    return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
 ScreenshotClient::ScreenshotClient()
     : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
 }
diff --git a/libs/utils/SystemClock.cpp b/libs/utils/SystemClock.cpp
index 8b8ac10..53e0626 100644
--- a/libs/utils/SystemClock.cpp
+++ b/libs/utils/SystemClock.cpp
@@ -106,7 +106,22 @@
  */
 int64_t elapsedRealtime()
 {
+	return nanoseconds_to_milliseconds(elapsedRealtimeNano());
+}
+
+/*
+ * native public static long elapsedRealtimeNano();
+ */
+int64_t elapsedRealtimeNano()
+{
 #ifdef HAVE_ANDROID_OS
+    struct timespec ts;
+    int result = clock_gettime(CLOCK_BOOTTIME, &ts);
+    if (result == 0) {
+        return seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
+    }
+
+    // CLOCK_BOOTTIME doesn't exist, fallback to /dev/alarm
     static int s_fd = -1;
 
     if (s_fd == -1) {
@@ -114,25 +129,20 @@
         if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
             close(fd);
         }
+        result = ioctl(s_fd,
+                ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
     }
 
-    struct timespec ts;
-    int result = ioctl(s_fd,
-            ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
-
     if (result == 0) {
-        int64_t when = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
-        return (int64_t) nanoseconds_to_milliseconds(when);
-    } else {
-        // XXX: there was an error, probably because the driver didn't
-        // exist ... this should return
-        // a real error, like an exception!
-        int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
-        return (int64_t) nanoseconds_to_milliseconds(when);
+        return seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
     }
+
+    // XXX: there was an error, probably because the driver didn't
+    // exist ... this should return
+    // a real error, like an exception!
+    return systemTime(SYSTEM_TIME_MONOTONIC);
 #else
-    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
-    return (int64_t) nanoseconds_to_milliseconds(when);
+    return systemTime(SYSTEM_TIME_MONOTONIC);
 #endif
 }
 
diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp
index 64b4701..d4f8516 100644
--- a/libs/utils/Timers.cpp
+++ b/libs/utils/Timers.cpp
@@ -39,7 +39,8 @@
             CLOCK_REALTIME,
             CLOCK_MONOTONIC,
             CLOCK_PROCESS_CPUTIME_ID,
-            CLOCK_THREAD_CPUTIME_ID
+            CLOCK_THREAD_CPUTIME_ID,
+            CLOCK_BOOTTIME
     };
     struct timespec t;
     t.tv_sec = t.tv_nsec = 0;
diff --git a/opengl/tools/glgen/src/EGLCodeEmitter.java b/opengl/tools/glgen/src/EGLCodeEmitter.java
index 1691b65..300f776 100644
--- a/opengl/tools/glgen/src/EGLCodeEmitter.java
+++ b/opengl/tools/glgen/src/EGLCodeEmitter.java
@@ -44,7 +44,7 @@
         mUseContextPointer = false;
         mUseStaticMethods = true;
         mUseSimpleMethodNames = true;
-        mUseHideCommentForAPI = true;
+        mUseHideCommentForAPI = false;
     }
 
     public void emitCode(CFunc cfunc, String original) {
diff --git a/opengl/tools/glgen/src/JniCodeEmitter.java b/opengl/tools/glgen/src/JniCodeEmitter.java
index af98889..726dc61 100644
--- a/opengl/tools/glgen/src/JniCodeEmitter.java
+++ b/opengl/tools/glgen/src/JniCodeEmitter.java
@@ -939,10 +939,13 @@
         // Emit a single _array or multiple _XXXArray variables
         if (numBufferArgs == 1) {
                 out.println(indent + "jarray _array = (jarray) 0;");
+                out.println(indent + "jint _bufferOffset = (jint) 0;");
         } else {
             for (int i = 0; i < numBufferArgs; i++) {
                 out.println(indent + "jarray _" + bufferArgNames.get(i) +
                             "Array = (jarray) 0;");
+                out.println(indent + "jint _" + bufferArgNames.get(i) +
+                            "BufferOffset = (jint) 0;");
             }
         }
         if (!isVoid) {
@@ -1075,7 +1078,6 @@
 
         // Emit 'GetPrimitiveArrayCritical' for non-object arrays
         // Emit 'GetPointer' calls for Buffer pointers
-        int bufArgIdx = 0;
         if (nonPrimitiveArgs.size() > 0) {
             for (int i = 0; i < nonPrimitiveArgs.size(); i++) {
                 int idx = nonPrimitiveArgs.get(i).intValue();
@@ -1168,7 +1170,9 @@
                     out.println();
                 } else if (jfunc.getArgType(idx).isBuffer()) {
                     String array = numBufferArgs <= 1 ? "_array" :
-                        "_" + bufferArgNames.get(bufArgIdx++) + "Array";
+                        "_" + cfunc.getArgName(cIndex) + "Array";
+                    String bufferOffset = numBufferArgs <= 1 ? "_bufferOffset" :
+                        "_" + cfunc.getArgName(cIndex) + "BufferOffset";
 
                     boolean nullAllowed = isNullAllowed(cfunc) || isPointerFunc;
                     if (nullAllowed) {
@@ -1194,7 +1198,7 @@
                                     cfunc.getArgType(cIndex).getDeclaration() +
                                     ")getPointer(_env, " +
                                     cname +
-                                    "_buf, &" + array + ", &" + remaining +
+                                    "_buf, &" + array + ", &" + remaining + ", &" + bufferOffset +
                                     ");");
                     }
 
@@ -1209,6 +1213,28 @@
             }
         }
 
+        // Emit 'GetPrimitiveArrayCritical' for pointers if needed
+        if (nonPrimitiveArgs.size() > 0) {
+            for (int i = 0; i < nonPrimitiveArgs.size(); i++) {
+                int idx = nonPrimitiveArgs.get(i).intValue();
+                int cIndex = jfunc.getArgCIndex(idx);
+
+                if(!jfunc.getArgType(idx).isBuffer() || isPointerFunc) continue;
+
+                String cname = cfunc.getArgName(cIndex);
+                String bufferOffset = numBufferArgs <= 1 ? "_bufferOffset" :
+                            "_" + cname + "BufferOffset";
+                String array = numBufferArgs <= 1 ? "_array" :
+                            "_" + cfunc.getArgName(cIndex) + "Array";
+
+                out.println(indent + "if (" + cname +" == NULL) {");
+                out.println(indent + indent + "char * _" + cname + "Base = (char *)_env->GetPrimitiveArrayCritical(" + array + ", (jboolean *) 0);");
+                out.println(indent + indent + cname + " = (" +cfunc.getArgType(cIndex).getDeclaration() +") (_" + cname + "Base + " + bufferOffset + ");");
+                out.println(indent + "}");
+             }
+        }
+
+
         if (!isVoid) {
             out.print(indent + "_returnValue = ");
         } else {
@@ -1252,7 +1278,7 @@
                     out.print("_native");
                 }
 
-		if (cfunc.getArgType(i).isEGLHandle() &&
+                if (cfunc.getArgType(i).isEGLHandle() &&
                     !cfunc.getArgType(i).isPointer()){
                     out.print(cfunc.getArgName(i)+"_native");
                 } else {
@@ -1279,7 +1305,7 @@
             needsExit = false;
         }
 
-        bufArgIdx = 0;
+
         if (nonPrimitiveArgs.size() > 0) {
             for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) {
                 int idx = nonPrimitiveArgs.get(i).intValue();
@@ -1307,7 +1333,7 @@
                 } else if (jfunc.getArgType(idx).isBuffer()) {
                     if (! isPointerFunc) {
                         String array = numBufferArgs <= 1 ? "_array" :
-                            "_" + bufferArgNames.get(bufArgIdx++) + "Array";
+                            "_" + cfunc.getArgName(cIndex) + "Array";
                         out.println(indent + "if (" + array + ") {");
                         out.println(indent + indent +
                                     "releasePointer(_env, " + array + ", " +
diff --git a/opengl/tools/glgen/static/egl/EGLConfig.java b/opengl/tools/glgen/static/egl/EGLConfig.java
index d9aebfc..d457c9f 100644
--- a/opengl/tools/glgen/static/egl/EGLConfig.java
+++ b/opengl/tools/glgen/static/egl/EGLConfig.java
@@ -18,10 +18,11 @@
 package android.opengl;
 
 /**
- * @hide
+ * Wrapper class for native EGLConfig objects.
+ *
  */
 public class EGLConfig extends EGLObjectHandle {
-    public EGLConfig(int handle) {
+    private EGLConfig(int handle) {
         super(handle);
     }
 
@@ -33,9 +34,4 @@
         EGLConfig that = (EGLConfig) o;
         return getHandle() == that.getHandle();
     }
-
-    @Override
-    public int hashCode() {
-        return getHandle();
-    }
 }
diff --git a/opengl/tools/glgen/static/egl/EGLContext.java b/opengl/tools/glgen/static/egl/EGLContext.java
index 7b194f3..41b8ef1 100644
--- a/opengl/tools/glgen/static/egl/EGLContext.java
+++ b/opengl/tools/glgen/static/egl/EGLContext.java
@@ -18,10 +18,11 @@
 package android.opengl;
 
 /**
- * @hide
+ * Wrapper class for native EGLContext objects.
+ *
  */
 public class EGLContext extends EGLObjectHandle {
-    public EGLContext(int handle) {
+    private EGLContext(int handle) {
         super(handle);
     }
 
@@ -33,9 +34,4 @@
         EGLContext that = (EGLContext) o;
         return getHandle() == that.getHandle();
     }
-
-    @Override
-    public int hashCode() {
-        return getHandle();
-    }
 }
diff --git a/opengl/tools/glgen/static/egl/EGLDisplay.java b/opengl/tools/glgen/static/egl/EGLDisplay.java
index a090cf0..17d1a64 100644
--- a/opengl/tools/glgen/static/egl/EGLDisplay.java
+++ b/opengl/tools/glgen/static/egl/EGLDisplay.java
@@ -18,10 +18,11 @@
 package android.opengl;
 
 /**
- * @hide
+ * Wrapper class for native EGLDisplay objects.
+ *
  */
 public class EGLDisplay extends EGLObjectHandle {
-    public EGLDisplay(int handle) {
+    private EGLDisplay(int handle) {
         super(handle);
     }
 
@@ -33,9 +34,4 @@
         EGLDisplay that = (EGLDisplay) o;
         return getHandle() == that.getHandle();
     }
-
-    @Override
-    public int hashCode() {
-        return getHandle();
-    }
 }
diff --git a/opengl/tools/glgen/static/egl/EGLObjectHandle.java b/opengl/tools/glgen/static/egl/EGLObjectHandle.java
index 01f9bd4..d2710de 100644
--- a/opengl/tools/glgen/static/egl/EGLObjectHandle.java
+++ b/opengl/tools/glgen/static/egl/EGLObjectHandle.java
@@ -18,16 +18,30 @@
 package android.opengl;
 
 /**
- * @hide
+ * Base class for wrapped EGL objects.
+ *
  */
 public abstract class EGLObjectHandle {
     private final int mHandle;
 
-    public EGLObjectHandle(int handle) {
+    protected EGLObjectHandle(int handle) {
         mHandle = handle;
     }
 
+    /**
+     * Returns the native handle of the wrapped EGL object. This handle can be
+     * cast to the corresponding native type on the native side.
+     *
+     * For example, EGLDisplay dpy = (EGLDisplay)handle;
+     *
+     * @return the native handle of the wrapped EGL object.
+     */
     public int getHandle() {
         return mHandle;
     }
+
+    @Override
+    public int hashCode() {
+        return getHandle();
+    }
 }
diff --git a/opengl/tools/glgen/static/egl/EGLSurface.java b/opengl/tools/glgen/static/egl/EGLSurface.java
index 4800a64..65bec4f 100644
--- a/opengl/tools/glgen/static/egl/EGLSurface.java
+++ b/opengl/tools/glgen/static/egl/EGLSurface.java
@@ -18,10 +18,11 @@
 package android.opengl;
 
 /**
- * @hide
+ * Wrapper class for native EGLSurface objects.
+ *
  */
 public class EGLSurface extends EGLObjectHandle {
-    public EGLSurface(int handle) {
+    private EGLSurface(int handle) {
         super(handle);
     }
 
@@ -33,9 +34,4 @@
         EGLSurface that = (EGLSurface) o;
         return getHandle() == that.getHandle();
     }
-
-    @Override
-    public int hashCode() {
-        return getHandle();
-    }
 }
diff --git a/opengl/tools/glgen/stubs/egl/EGL14Header.java-if b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if
index 9330c99..0c29d5c 100644
--- a/opengl/tools/glgen/stubs/egl/EGL14Header.java-if
+++ b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if
@@ -23,10 +23,10 @@
 import android.view.SurfaceView;
 import android.view.SurfaceHolder;
 
-
 /**
-* @hide
-*/
+ * EGL 1.4
+ *
+ */
 public class EGL14 {
 
 public static final int EGL_DEFAULT_DISPLAY            = 0;
diff --git a/opengl/tools/glgen/stubs/gles11/GLES10ExtcHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES10ExtcHeader.cpp
index 5d418d7..172c0e7 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES10ExtcHeader.cpp
+++ b/opengl/tools/glgen/stubs/gles11/GLES10ExtcHeader.cpp
@@ -62,14 +62,12 @@
 
 
 static void *
-getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining)
+getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset)
 {
     jint position;
     jint limit;
     jint elementSizeShift;
     jlong pointer;
-    jint offset;
-    void *data;
 
     position = _env->GetIntField(buffer, positionID);
     limit = _env->GetIntField(buffer, limitID);
@@ -84,11 +82,10 @@
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
             getBaseArrayID, buffer);
-    offset = _env->CallStaticIntMethod(nioAccessClass,
+    *offset = _env->CallStaticIntMethod(nioAccessClass,
             getBaseArrayOffsetID, buffer);
-    data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
 
-    return (void *) ((char *) data + offset);
+    return NULL;
 }
 
 
diff --git a/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp
index 35a3c33..4ef815b 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp
+++ b/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp
@@ -74,14 +74,12 @@
 }
 
 static void *
-getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining)
+getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset)
 {
     jint position;
     jint limit;
     jint elementSizeShift;
     jlong pointer;
-    jint offset;
-    void *data;
 
     position = _env->GetIntField(buffer, positionID);
     limit = _env->GetIntField(buffer, limitID);
@@ -96,11 +94,10 @@
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
             getBaseArrayID, buffer);
-    offset = _env->CallStaticIntMethod(nioAccessClass,
+    *offset = _env->CallStaticIntMethod(nioAccessClass,
             getBaseArrayOffsetID, buffer);
-    data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
 
-    return (void *) ((char *) data + offset);
+    return NULL;
 }
 
 static void
diff --git a/opengl/tools/glgen/stubs/gles11/GLES11ExtcHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES11ExtcHeader.cpp
index 9b29a44..0df95f4 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES11ExtcHeader.cpp
+++ b/opengl/tools/glgen/stubs/gles11/GLES11ExtcHeader.cpp
@@ -71,14 +71,12 @@
 
 
 static void *
-getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining)
+getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset)
 {
     jint position;
     jint limit;
     jint elementSizeShift;
     jlong pointer;
-    jint offset;
-    void *data;
 
     position = _env->GetIntField(buffer, positionID);
     limit = _env->GetIntField(buffer, limitID);
@@ -93,11 +91,9 @@
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
             getBaseArrayID, buffer);
-    offset = _env->CallStaticIntMethod(nioAccessClass,
+    *offset = _env->CallStaticIntMethod(nioAccessClass,
             getBaseArrayOffsetID, buffer);
-    data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
-
-    return (void *) ((char *) data + offset);
+    return NULL;
 }
 
 
diff --git a/opengl/tools/glgen/stubs/gles11/GLES11cHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES11cHeader.cpp
index 823079f..dd860d5 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES11cHeader.cpp
+++ b/opengl/tools/glgen/stubs/gles11/GLES11cHeader.cpp
@@ -69,14 +69,12 @@
 
 
 static void *
-getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining)
+getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset)
 {
     jint position;
     jint limit;
     jint elementSizeShift;
     jlong pointer;
-    jint offset;
-    void *data;
 
     position = _env->GetIntField(buffer, positionID);
     limit = _env->GetIntField(buffer, limitID);
@@ -91,11 +89,10 @@
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
             getBaseArrayID, buffer);
-    offset = _env->CallStaticIntMethod(nioAccessClass,
+    *offset = _env->CallStaticIntMethod(nioAccessClass,
             getBaseArrayOffsetID, buffer);
-    data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
 
-    return (void *) ((char *) data + offset);
+    return NULL;
 }
 
 
diff --git a/opengl/tools/glgen/stubs/gles11/GLES20cHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES20cHeader.cpp
index 13a2577..996f441 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES20cHeader.cpp
+++ b/opengl/tools/glgen/stubs/gles11/GLES20cHeader.cpp
@@ -62,14 +62,12 @@
 
 
 static void *
-getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining)
+getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset)
 {
     jint position;
     jint limit;
     jint elementSizeShift;
     jlong pointer;
-    jint offset;
-    void *data;
 
     position = _env->GetIntField(buffer, positionID);
     limit = _env->GetIntField(buffer, limitID);
@@ -84,11 +82,10 @@
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
             getBaseArrayID, buffer);
-    offset = _env->CallStaticIntMethod(nioAccessClass,
+    *offset = _env->CallStaticIntMethod(nioAccessClass,
             getBaseArrayOffsetID, buffer);
-    data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
 
-    return (void *) ((char *) data + offset);
+    return NULL;
 }
 
 
diff --git a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
index f7315ee..cc10336 100644
--- a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
+++ b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
@@ -113,14 +113,12 @@
 }
 
 static void *
-getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining)
+getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset)
 {
     jint position;
     jint limit;
     jint elementSizeShift;
     jlong pointer;
-    jint offset;
-    void *data;
 
     position = _env->GetIntField(buffer, positionID);
     limit = _env->GetIntField(buffer, limitID);
@@ -138,11 +136,10 @@
     if (*array == NULL) {
         return (void*) NULL;
     }
-    offset = _env->CallStaticIntMethod(nioAccessClass,
+    *offset = _env->CallStaticIntMethod(nioAccessClass,
             getBaseArrayOffsetID, buffer);
-    data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
 
-    return (void *) ((char *) data + offset);
+    return NULL;
 }
 
 static void
@@ -180,10 +177,12 @@
         if (allowIndirectBuffers(_env)) {
             jarray array = 0;
             jint remaining;
-            buf = getPointer(_env, buffer, &array, &remaining);
+            jint offset;
+            buf = getPointer(_env, buffer, &array, &remaining, &offset);
             if (array) {
                 releasePointer(_env, array, buf, 0);
             }
+            buf = buf + offset;
         } else {
             jniThrowException(_env, "java/lang/IllegalArgumentException",
                               "Must use a native order direct Buffer");
diff --git a/services/surfaceflinger/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware.cpp
index eac9e04..af33a89 100644
--- a/services/surfaceflinger/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware.cpp
@@ -31,6 +31,7 @@
 #include <EGL/eglext.h>
 
 #include <hardware/gralloc.h>
+#include <private/gui/SharedBufferStack.h>
 
 #include "DisplayHardware/FramebufferSurface.h"
 #include "DisplayHardware/DisplayHardwareBase.h"
@@ -40,8 +41,9 @@
 #include "GLExtensions.h"
 #include "SurfaceFlinger.h"
 
+// ----------------------------------------------------------------------------
 using namespace android;
-
+// ----------------------------------------------------------------------------
 
 static __attribute__((noinline))
 void checkGLErrors()
@@ -88,6 +90,8 @@
     }
 }
 
+// ----------------------------------------------------------------------------
+
 /*
  * Initialize the display to the specified values.
  *
@@ -95,79 +99,78 @@
 
 DisplayHardware::DisplayHardware(
         const sp<SurfaceFlinger>& flinger,
-        uint32_t dpy)
-    : DisplayHardwareBase(flinger, dpy),
-      mFlinger(flinger), mFlags(0), mHwc(0)
+        int display,
+        const sp<SurfaceTextureClient>& surface,
+        EGLConfig config)
+    : DisplayHardwareBase(flinger, display),
+      mFlinger(flinger),
+      mDisplayId(display),
+      mHwc(0),
+      mNativeWindow(surface),
+      mFlags(0),
+      mSecureLayerVisible(false)
 {
-    init(dpy);
+    init(config);
 }
 
-DisplayHardware::~DisplayHardware()
-{
-    fini();
+DisplayHardware::~DisplayHardware() {
 }
 
-float DisplayHardware::getDpiX() const          { return mDpiX; }
-float DisplayHardware::getDpiY() const          { return mDpiY; }
-float DisplayHardware::getDensity() const       { return mDensity; }
-float DisplayHardware::getRefreshRate() const   { return mRefreshRate; }
-int DisplayHardware::getWidth() const           { return mDisplayWidth; }
-int DisplayHardware::getHeight() const          { return mDisplayHeight; }
-PixelFormat DisplayHardware::getFormat() const  { return mFormat; }
-uint32_t DisplayHardware::getMaxTextureSize() const { return mMaxTextureSize; }
-
-uint32_t DisplayHardware::getMaxViewportDims() const {
-    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
-            mMaxViewportDims[0] : mMaxViewportDims[1];
+float DisplayHardware::getDpiX() const {
+    return mDpiX;
 }
 
-static status_t selectConfigForPixelFormat(
-        EGLDisplay dpy,
-        EGLint const* attrs,
-        PixelFormat format,
-        EGLConfig* outConfig)
-{
-    EGLConfig config = NULL;
-    EGLint numConfigs = -1, n=0;
-    eglGetConfigs(dpy, NULL, 0, &numConfigs);
-    EGLConfig* const configs = new EGLConfig[numConfigs];
-    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
-    for (int i=0 ; i<n ; i++) {
-        EGLint nativeVisualId = 0;
-        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
-        if (nativeVisualId>0 && format == nativeVisualId) {
-            *outConfig = configs[i];
-            delete [] configs;
-            return NO_ERROR;
-        }
-    }
-    delete [] configs;
-    return NAME_NOT_FOUND;
+float DisplayHardware::getDpiY() const {
+    return mDpiY;
 }
 
+float DisplayHardware::getDensity() const {
+    return mDensity;
+}
 
-void DisplayHardware::init(uint32_t dpy)
+float DisplayHardware::getRefreshRate() const {
+    return mRefreshRate;
+}
+
+int DisplayHardware::getWidth() const {
+    return mDisplayWidth;
+}
+
+int DisplayHardware::getHeight() const {
+    return mDisplayHeight;
+}
+
+PixelFormat DisplayHardware::getFormat() const {
+    return mFormat;
+}
+
+EGLSurface DisplayHardware::getEGLSurface() const {
+    return mSurface;
+}
+
+void DisplayHardware::init(EGLConfig config)
 {
-    mNativeWindow = new FramebufferSurface();
-    framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
-    if (!fbDev) {
-        ALOGE("Display subsystem failed to initialize. check logs. exiting...");
-        exit(0);
+    ANativeWindow* const window = mNativeWindow.get();
+
+    int concreteType;
+    window->query(window, NATIVE_WINDOW_CONCRETE_TYPE, &concreteType);
+    if (concreteType == NATIVE_WINDOW_FRAMEBUFFER) {
+        mFramebufferSurface = static_cast<FramebufferSurface *>(mNativeWindow.get());
     }
 
     int format;
-    ANativeWindow const * const window = mNativeWindow.get();
     window->query(window, NATIVE_WINDOW_FORMAT, &format);
-    mDpiX = mNativeWindow->xdpi;
-    mDpiY = mNativeWindow->ydpi;
-    mRefreshRate = fbDev->fps;
-
-    if (mDpiX == 0 || mDpiY == 0) {
-        ALOGE("invalid screen resolution from fb HAL (xdpi=%f, ydpi=%f), "
-               "defaulting to 160 dpi", mDpiX, mDpiY);
-        mDpiX = mDpiY = 160;
+    mDpiX = window->xdpi;
+    mDpiY = window->ydpi;
+    if (mFramebufferSurface != NULL) {
+        mRefreshRate = mFramebufferSurface->getRefreshRate();
+    } else {
+        mRefreshRate = 60;
     }
+    mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
 
+
+    // TODO: Not sure if display density should handled by SF any longer
     class Density {
         static int getDensityFromProperty(char const* propName) {
             char property[PROPERTY_VALUE_MAX];
@@ -183,173 +186,52 @@
         static int getBuildDensity()  {
             return getDensityFromProperty("ro.sf.lcd_density"); }
     };
-
-
     // The density of the device is provided by a build property
     mDensity = Density::getBuildDensity() / 160.0f;
-
     if (mDensity == 0) {
         // the build doesn't provide a density -- this is wrong!
         // use xdpi instead
         ALOGE("ro.sf.lcd_density must be defined as a build property");
         mDensity = mDpiX / 160.0f;
     }
-
     if (Density::getEmuDensity()) {
         // if "qemu.sf.lcd_density" is specified, it overrides everything
         mDpiX = mDpiY = mDensity = Density::getEmuDensity();
         mDensity /= 160.0f;
     }
 
-
-
-    /* FIXME: this is a temporary HACK until we are able to report the refresh rate
-     * properly from the HAL. The WindowManagerService now relies on this value.
-     */
-#ifndef REFRESH_RATE
-    mRefreshRate = fbDev->fps;
-#else
-    mRefreshRate = REFRESH_RATE;
-#warning "refresh rate set via makefile to REFRESH_RATE"
-#endif
-
-    mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
-
-    EGLint w, h, dummy;
-    EGLint numConfigs=0;
-    EGLSurface surface;
-    EGLContext context;
-    EGLBoolean result;
-    status_t err;
-
-    // initialize EGL
-    EGLint attribs[] = {
-            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
-            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
-            EGL_NONE
-    };
-
-    // TODO: all the extensions below should be queried through
-    // eglGetProcAddress().
-
-    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    eglInitialize(display, NULL, NULL);
-    eglGetConfigs(display, NULL, 0, &numConfigs);
-
-    EGLConfig config = NULL;
-    err = selectConfigForPixelFormat(display, attribs, format, &config);
-    if (err) {
-        // maybe we failed because of EGL_RECORDABLE_ANDROID
-        ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
-        attribs[2] = EGL_NONE;
-        err = selectConfigForPixelFormat(display, attribs, format, &config);
-    }
-
-    ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
-    
-    EGLint r,g,b,a;
-    eglGetConfigAttrib(display, config, EGL_RED_SIZE,   &r);
-    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);
-    eglGetConfigAttrib(display, config, EGL_BLUE_SIZE,  &b);
-    eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);
-
-    if (mNativeWindow->isUpdateOnDemand()) {
-        mFlags |= PARTIAL_UPDATES;
-    }
-    
-    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
-        if (dummy == EGL_SLOW_CONFIG)
-            mFlags |= SLOW_CONFIG;
-    }
-
     /*
-     * Create our main surface
+     * Create our display's surface
      */
 
-    surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
+    EGLSurface surface;
+    EGLint w, h;
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    surface = eglCreateWindowSurface(display, config, window, NULL);
     eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);
     eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
 
-    if (mFlags & PARTIAL_UPDATES) {
-        // if we have partial updates, we definitely don't need to
-        // preserve the backbuffer, which may be costly.
-        eglSurfaceAttrib(display, surface,
-                EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
+    if (mFramebufferSurface != NULL) {
+        if (mFramebufferSurface->isUpdateOnDemand()) {
+            mFlags |= PARTIAL_UPDATES;
+            // if we have partial updates, we definitely don't need to
+            // preserve the backbuffer, which may be costly.
+            eglSurfaceAttrib(display, surface,
+                    EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
+        }
     }
 
-    /*
-     * Create our OpenGL ES context
-     */
-    
-    EGLint contextAttributes[] = {
-#ifdef EGL_IMG_context_priority
-#ifdef HAS_CONTEXT_PRIORITY
-#warning "using EGL_IMG_context_priority"
-        EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
-#endif
-#endif
-        EGL_NONE, EGL_NONE
-    };
-    context = eglCreateContext(display, config, NULL, contextAttributes);
-
     mDisplay = display;
-    mConfig  = config;
     mSurface = surface;
-    mContext = context;
-    mFormat  = fbDev->format;
+    mFormat  = format;
     mPageFlipCount = 0;
 
-    /*
-     * Gather OpenGL ES extensions
-     */
-
-    result = eglMakeCurrent(display, surface, surface, context);
-    if (!result) {
-        ALOGE("Couldn't create a working GLES context. check logs. exiting...");
-        exit(0);
-    }
-
-    GLExtensions& extensions(GLExtensions::getInstance());
-    extensions.initWithGLStrings(
-            glGetString(GL_VENDOR),
-            glGetString(GL_RENDERER),
-            glGetString(GL_VERSION),
-            glGetString(GL_EXTENSIONS),
-            eglQueryString(display, EGL_VENDOR),
-            eglQueryString(display, EGL_VERSION),
-            eglQueryString(display, EGL_EXTENSIONS));
-
-    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
-    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
-
-    ALOGI("EGL informations:");
-    ALOGI("# of configs : %d", numConfigs);
-    ALOGI("vendor    : %s", extensions.getEglVendor());
-    ALOGI("version   : %s", extensions.getEglVersion());
-    ALOGI("extensions: %s", extensions.getEglExtension());
-    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
-    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config);
-
-    ALOGI("OpenGL informations:");
-    ALOGI("vendor    : %s", extensions.getVendor());
-    ALOGI("renderer  : %s", extensions.getRenderer());
-    ALOGI("version   : %s", extensions.getVersion());
-    ALOGI("extensions: %s", extensions.getExtension());
-    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
-    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
-    ALOGI("flags = %08x", mFlags);
-
-    // Unbind the context from this thread
-    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-
     // initialize the H/W composer
     mHwc = new HWComposer(mFlinger, *this, mRefreshPeriod);
     if (mHwc->initCheck() == NO_ERROR) {
         mHwc->setFrameBuffer(mDisplay, mSurface);
     }
 
-
     // initialize the display orientation transform.
     // it's a constant that should come from the display driver.
     int displayOrientation = ISurfaceComposer::eOrientationDefault;
@@ -378,6 +260,20 @@
         mLogicalDisplayHeight = h;
     }
     DisplayHardware::setOrientation(ISurfaceComposer::eOrientationDefault);
+
+    // initialize the shared control block
+    surface_flinger_cblk_t* const scblk = mFlinger->getControlBlock();
+    scblk->connected |= 1 << mDisplayId;
+    display_cblk_t* dcblk = &scblk->displays[mDisplayId];
+    memset(dcblk, 0, sizeof(display_cblk_t));
+    dcblk->w = w; // XXX: plane.getWidth();
+    dcblk->h = h; // XXX: plane.getHeight();
+    dcblk->format = format;
+    dcblk->orientation = ISurfaceComposer::eOrientationDefault;
+    dcblk->xdpi = mDpiX;
+    dcblk->ydpi = mDpiY;
+    dcblk->fps = mRefreshRate;
+    dcblk->density = mDensity;
 }
 
 void DisplayHardware::setVSyncHandler(const sp<VSyncHandler>& handler) {
@@ -411,19 +307,6 @@
     return *mHwc;
 }
 
-/*
- * Clean up.  Throw out our local state.
- *
- * (It's entirely possible we'll never get here, since this is meant
- * for real hardware, which doesn't restart.)
- */
-
-void DisplayHardware::fini()
-{
-    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    eglTerminate(mDisplay);
-}
-
 void DisplayHardware::releaseScreen() const
 {
     DisplayHardwareBase::releaseScreen();
@@ -434,6 +317,9 @@
 
 void DisplayHardware::acquireScreen() const
 {
+    if (mHwc->initCheck() == NO_ERROR) {
+        mHwc->acquire();
+    }
     DisplayHardwareBase::acquireScreen();
 }
 
@@ -455,7 +341,10 @@
 }
 
 status_t DisplayHardware::compositionComplete() const {
-    return mNativeWindow->compositionComplete();
+    if (mFramebufferSurface == NULL) {
+        return NO_ERROR;
+    }
+    return mFramebufferSurface->compositionComplete();
 }
 
 void DisplayHardware::flip(const Region& dirty) const
@@ -475,7 +364,9 @@
 #endif
     
     if (mFlags & PARTIAL_UPDATES) {
-        mNativeWindow->setUpdateRectangle(dirty.getBounds());
+        if (mFramebufferSurface != NULL) {
+            mFramebufferSurface->setUpdateRectangle(dirty.getBounds());
+        }
     }
     
     mPageFlipCount++;
@@ -486,10 +377,6 @@
         eglSwapBuffers(dpy, surface);
     }
     checkEGLErrors("eglSwapBuffers");
-
-    // for debugging
-    //glClearColor(1,0,0,0);
-    //glClear(GL_COLOR_BUFFER_BIT);
 }
 
 uint32_t DisplayHardware::getFlags() const
@@ -497,14 +384,31 @@
     return mFlags;
 }
 
-void DisplayHardware::makeCurrent() const
-{
-    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
-}
-
 void DisplayHardware::dump(String8& res) const
 {
-    mNativeWindow->dump(res);
+    if (mFramebufferSurface != NULL) {
+        mFramebufferSurface->dump(res);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+void DisplayHardware::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) {
+    mVisibleLayersSortedByZ = layers;
+    size_t count = layers.size();
+    for (size_t i=0 ; i<count ; i++) {
+        if (layers[i]->isSecure()) {
+            mSecureLayerVisible = true;
+        }
+    }
+}
+
+Vector< sp<LayerBase> > DisplayHardware::getVisibleLayersSortedByZ() const {
+    return mVisibleLayersSortedByZ;
+}
+
+bool DisplayHardware::getSecureLayerVisible() const {
+    return mSecureLayerVisible;
 }
 
 // ----------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware.h b/services/surfaceflinger/DisplayHardware.h
index 3da9f16..029c3da 100644
--- a/services/surfaceflinger/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware.h
@@ -27,7 +27,6 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#include "GLExtensions.h"
 #include "Transform.h"
 
 #include "DisplayHardware/DisplayHardwareBase.h"
@@ -37,6 +36,7 @@
 namespace android {
 
 class FramebufferSurface;
+class SurfaceTextureClient;
 
 class DisplayHardware :
     public DisplayHardwareBase,
@@ -52,15 +52,15 @@
     };
 
     enum {
-        COPY_BITS_EXTENSION         = 0x00000008,
         PARTIAL_UPDATES             = 0x00020000,   // video driver feature
-        SLOW_CONFIG                 = 0x00040000,   // software
         SWAP_RECTANGLE              = 0x00080000,
     };
 
     DisplayHardware(
             const sp<SurfaceFlinger>& flinger,
-            uint32_t displayIndex);
+            int dpy,
+            const sp<SurfaceTextureClient>& surface,
+            EGLConfig config);
 
     virtual ~DisplayHardware();
 
@@ -79,11 +79,14 @@
     int         getHeight() const;
     PixelFormat getFormat() const;
     uint32_t    getFlags() const;
-    uint32_t    getMaxTextureSize() const;
-    uint32_t    getMaxViewportDims() const;
     nsecs_t     getRefreshPeriod() const;
     nsecs_t     getRefreshTimestamp() const;
-    void        makeCurrent() const;
+
+    EGLSurface  getEGLSurface() const;
+
+    void                    setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers);
+    Vector< sp<LayerBase> > getVisibleLayersSortedByZ() const;
+    bool                    getSecureLayerVisible() const;
 
     status_t                setOrientation(int orientation);
     int                     getOrientation() const { return mOrientation; }
@@ -102,7 +105,6 @@
 
     uint32_t getPageFlipCount() const;
     EGLDisplay getEGLDisplay() const { return mDisplay; }
-    EGLConfig getEGLConfig() const { return mConfig; }
 
     void dump(String8& res) const;
 
@@ -117,15 +119,26 @@
     inline Rect bounds() const { return getBounds(); }
 
 private:
-    virtual void onVSyncReceived(int dpy, nsecs_t timestamp);
-    void init(uint32_t displayIndex);
-    void fini();
+    void init(EGLConfig config);
 
+    virtual void onVSyncReceived(int dpy, nsecs_t timestamp);
+
+    /*
+     *  Constants, set during initialization
+     */
     sp<SurfaceFlinger> mFlinger;
+    int mDisplayId;
+    HWComposer* mHwc;
+    PowerHAL mPowerHAL;
+    // ANativeWindow this display is rendering into
+    sp<SurfaceTextureClient> mNativeWindow;
+    // set if mNativeWindow is a FramebufferSurface
+    sp<FramebufferSurface> mFramebufferSurface;
+
+
     EGLDisplay      mDisplay;
     EGLSurface      mSurface;
     EGLContext      mContext;
-    EGLConfig       mConfig;
     float           mDpiX;
     float           mDpiY;
     float           mRefreshRate;
@@ -135,15 +148,19 @@
     PixelFormat     mFormat;
     uint32_t        mFlags;
     mutable uint32_t mPageFlipCount;
-    GLint           mMaxViewportDims[2];
-    GLint           mMaxTextureSize;
 
     nsecs_t         mRefreshPeriod;
     mutable nsecs_t mLastHwVSync;
 
-    // constant once set
-    HWComposer*     mHwc;
-    PowerHAL        mPowerHAL;
+
+    /*
+     * Can only accessed from the main thread, these members
+     * don't need synchronization.
+     */
+    // list of visible layers on that display
+    Vector< sp<LayerBase> > mVisibleLayersSortedByZ;
+    // Whether we have a visible secure layer on this display
+    bool mSecureLayerVisible;
 
 
     // this used to be in GraphicPlane
@@ -157,13 +174,12 @@
     int                     mUserDisplayWidth;
     int                     mUserDisplayHeight;
 
-
     mutable Mutex   mLock;
 
-    // protected by mLock
+    /*
+     *  protected by mLock
+     */
     wp<VSyncHandler>    mVSyncHandler;
-
-    sp<FramebufferSurface> mNativeWindow;
 };
 
 }; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 6cfb190..7695e7f 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -38,6 +38,15 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
+sp<FramebufferSurface> FramebufferSurface::create() {
+    sp<FramebufferSurface> result = new FramebufferSurface();
+    if (result->fbDev == NULL) {
+        result = NULL;
+    }
+    return result;
+}
+
+// ----------------------------------------------------------------------------
 
 /*
  * This implements the (main) framebuffer management. This class is used
@@ -64,10 +73,19 @@
         mUpdateOnDemand = (fbDev->setUpdateRect != 0);
 
         const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags;
-        const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi;
-        const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi;
         const_cast<int&>(ANativeWindow::minSwapInterval) =  fbDev->minSwapInterval;
         const_cast<int&>(ANativeWindow::maxSwapInterval) =  fbDev->maxSwapInterval;
+
+        if (fbDev->xdpi == 0 || fbDev->ydpi == 0) {
+            ALOGE("invalid screen resolution from fb HAL (xdpi=%f, ydpi=%f), "
+                   "defaulting to 160 dpi", fbDev->xdpi, fbDev->ydpi);
+            const_cast<float&>(ANativeWindow::xdpi) = 160;
+            const_cast<float&>(ANativeWindow::ydpi) = 160;
+        } else {
+            const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi;
+            const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi;
+        }
+
     } else {
         ALOGE("Couldn't get gralloc module");
     }
@@ -139,6 +157,19 @@
     }
 }
 
+float FramebufferSurface::getRefreshRate() const {
+    /* FIXME: REFRESH_RATE is a temporary HACK until we are able to report the
+     * refresh rate properly from the HAL. The WindowManagerService now relies
+     * on this value.
+     */
+#ifndef REFRESH_RATE
+    return fbDev->fps;
+#else
+    return REFRESH_RATE;
+#warning "refresh rate set via makefile to REFRESH_RATE"
+#endif
+}
+
 status_t FramebufferSurface::setUpdateRectangle(const Rect& r)
 {
     if (!mUpdateOnDemand) {
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 5b4fd01..672bfbb 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -37,11 +37,11 @@
 
 class FramebufferSurface : public SurfaceTextureClient {
 public:
-    FramebufferSurface();
 
-    virtual void onFirstRef();
+    static sp<FramebufferSurface> create();
 
-    framebuffer_device_t const * getDevice() const { return fbDev; }
+    // TODO: this should be coming from HWC
+    float getRefreshRate() const;
 
     bool isUpdateOnDemand() const { return mUpdateOnDemand; }
     status_t setUpdateRectangle(const Rect& updateRect);
@@ -49,7 +49,11 @@
 
     void dump(String8& result);
 
+protected:
+    virtual void onFirstRef();
+
 private:
+    FramebufferSurface();
     virtual ~FramebufferSurface(); // this class cannot be overloaded
     virtual int query(int what, int* value) const;
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 4ed692f..122be5e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -286,11 +286,33 @@
             mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0);
         }
         int err = mHwc->set(mHwc, NULL, NULL, NULL);
+        if (err < 0) {
+            return (status_t)err;
+        }
+
+        if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+            if (mHwc->methods && mHwc->methods->blank) {
+                err = mHwc->methods->blank(mHwc, 1);
+            }
+        }
         return (status_t)err;
     }
     return NO_ERROR;
 }
 
+status_t HWComposer::acquire() const {
+    if (mHwc) {
+        if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+            if (mHwc->methods && mHwc->methods->blank) {
+                int err = mHwc->methods->blank(mHwc, 0);
+                return (status_t)err;
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
 status_t HWComposer::disable() {
     if (mHwc) {
         free(mList);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index a662b25..5cde7fb 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -71,9 +71,12 @@
     // commits the list
     status_t commit() const;
 
-    // release hardware resources
+    // release hardware resources and blank screen
     status_t release() const;
 
+    // acquire hardware resources and unblank screen
+    status_t acquire() const;
+
     // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED.
     status_t createWorkList(size_t numLayers);
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index a09b5c7..b2f2683 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -182,11 +182,8 @@
         return err;
     }
 
-    // the display's pixel format
-    // XXX: we shouldn't rely on the DisplayHardware to do this
-    const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware());
     uint32_t const maxSurfaceDims = min(
-            hw.getMaxTextureSize(), hw.getMaxViewportDims());
+            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
 
     // never allow a surface larger than what our underlying GL implementation
     // can handle.
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index d227b2d..c689297 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -25,6 +25,7 @@
 #include <GLES/gl.h>
 
 #include <utils/RefBase.h>
+#include <utils/String8.h>
 
 #include <ui/Region.h>
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 6c900be..840222c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -59,6 +59,7 @@
 #include "LayerScreenshot.h"
 #include "SurfaceFlinger.h"
 
+#include "DisplayHardware/FramebufferSurface.h"
 #include "DisplayHardware/HWComposer.h"
 
 #include <private/android_filesystem_config.h>
@@ -98,7 +99,6 @@
         mDebugInTransaction(0),
         mLastTransactionTime(0),
         mBootFinished(false),
-        mSecureFrameBuffer(0),
         mExternalDisplaySurface(EGL_NO_SURFACE)
 {
     init();
@@ -142,6 +142,9 @@
 SurfaceFlinger::~SurfaceFlinger()
 {
     glDeleteTextures(1, &mWormholeTexName);
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    eglTerminate(display);
 }
 
 void SurfaceFlinger::binderDied(const wp<IBinder>& who)
@@ -198,59 +201,95 @@
     property_set("service.bootanim.exit", "1");
 }
 
-static inline uint16_t pack565(int r, int g, int b) {
-    return (r<<11)|(g<<5)|b;
+status_t SurfaceFlinger::selectConfigForPixelFormat(
+        EGLDisplay dpy,
+        EGLint const* attrs,
+        PixelFormat format,
+        EGLConfig* outConfig)
+{
+    EGLConfig config = NULL;
+    EGLint numConfigs = -1, n=0;
+    eglGetConfigs(dpy, NULL, 0, &numConfigs);
+    EGLConfig* const configs = new EGLConfig[numConfigs];
+    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
+    for (int i=0 ; i<n ; i++) {
+        EGLint nativeVisualId = 0;
+        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
+        if (nativeVisualId>0 && format == nativeVisualId) {
+            *outConfig = configs[i];
+            delete [] configs;
+            return NO_ERROR;
+        }
+    }
+    delete [] configs;
+    return NAME_NOT_FOUND;
 }
 
-status_t SurfaceFlinger::readyToRun()
-{
-    ALOGI(  "SurfaceFlinger's main thread ready to run. "
-            "Initializing graphics H/W...");
+EGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
+    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
+    // it is to be used with WIFI displays
+    EGLConfig config;
+    EGLint dummy;
+    status_t err;
+    EGLint attribs[] = {
+            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
+            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
+            EGL_NONE
+    };
+    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
+    if (err) {
+        // maybe we failed because of EGL_RECORDABLE_ANDROID
+        ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
+        attribs[2] = EGL_NONE;
+        err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
+    }
+    ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
+    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
+        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
+    }
+    return config;
+}
 
-    // we only support one display currently
-    int dpy = 0;
+EGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
+    // Also create our EGLContext
+    EGLint contextAttributes[] = {
+#ifdef EGL_IMG_context_priority
+#ifdef HAS_CONTEXT_PRIORITY
+#warning "using EGL_IMG_context_priority"
+            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
+#endif
+#endif
+            EGL_NONE, EGL_NONE
+    };
+    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
+    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
+    return ctxt;
+}
 
-    {
-        // initialize the main display
-        // TODO: initialize all displays
-        DisplayHardware* const hw = new DisplayHardware(this, dpy);
-        mDisplayHardwares[0] = hw;
+void SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
+    EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext);
+    if (!result) {
+        ALOGE("Couldn't create a working GLES context. check logs. exiting...");
+        exit(0);
     }
 
-    // create the shared control-block
-    mServerHeap = new MemoryHeapBase(4096,
-            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
-    ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
+    GLExtensions& extensions(GLExtensions::getInstance());
+    extensions.initWithGLStrings(
+            glGetString(GL_VENDOR),
+            glGetString(GL_RENDERER),
+            glGetString(GL_VERSION),
+            glGetString(GL_EXTENSIONS),
+            eglQueryString(display, EGL_VENDOR),
+            eglQueryString(display, EGL_VERSION),
+            eglQueryString(display, EGL_EXTENSIONS));
 
-    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
-    ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
+    EGLint w, h;
+    eglQuerySurface(display, surface, EGL_WIDTH,  &w);
+    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
 
-    new(mServerCblk) surface_flinger_cblk_t;
+    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
+    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
 
-    // initialize primary screen
-    // (other display should be initialized in the same manner, but
-    // asynchronously, as they could come and go. None of this is supported
-    // yet).
-    const DisplayHardware& hw(getDefaultDisplayHardware());
-    const uint32_t w = hw.getWidth();
-    const uint32_t h = hw.getHeight();
-    const uint32_t f = hw.getFormat();
-    hw.makeCurrent();
-
-    // initialize the shared control block
-    mServerCblk->connected |= 1<<dpy;
-    display_cblk_t* dcblk = mServerCblk->displays + dpy;
-    memset(dcblk, 0, sizeof(display_cblk_t));
-    dcblk->w            = w; // XXX: plane.getWidth();
-    dcblk->h            = h; // XXX: plane.getHeight();
-    dcblk->format       = f;
-    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
-    dcblk->xdpi         = hw.getDpiX();
-    dcblk->ydpi         = hw.getDpiY();
-    dcblk->fps          = hw.getRefreshRate();
-    dcblk->density      = hw.getDensity();
-
-    // Initialize OpenGL|ES
     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
     glPixelStorei(GL_PACK_ALIGNMENT, 4);
     glEnableClientState(GL_VERTEX_ARRAY);
@@ -258,6 +297,12 @@
     glDisable(GL_DITHER);
     glDisable(GL_CULL_FACE);
 
+    struct pack565 {
+        inline uint16_t operator() (int r, int g, int b) const {
+            return (r<<11)|(g<<5)|b;
+        }
+    } pack565;
+
     const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
     const uint16_t g1 = pack565(0x17,0x2f,0x17);
     const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
@@ -286,15 +331,77 @@
     // put the origin in the left-bottom corner
     glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
 
+    // print some debugging info
+    EGLint r,g,b,a;
+    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
+    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
+    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
+    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
+    ALOGI("EGL informations:");
+    ALOGI("vendor    : %s", extensions.getEglVendor());
+    ALOGI("version   : %s", extensions.getEglVersion());
+    ALOGI("extensions: %s", extensions.getEglExtension());
+    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
+    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
+    ALOGI("OpenGL ES informations:");
+    ALOGI("vendor    : %s", extensions.getVendor());
+    ALOGI("renderer  : %s", extensions.getRenderer());
+    ALOGI("version   : %s", extensions.getVersion());
+    ALOGI("extensions: %s", extensions.getExtension());
+    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
+    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
+}
+
+surface_flinger_cblk_t* SurfaceFlinger::getControlBlock() const {
+    return mServerCblk;
+}
+
+status_t SurfaceFlinger::readyToRun()
+{
+    ALOGI(  "SurfaceFlinger's main thread ready to run. "
+            "Initializing graphics H/W...");
+
+    // create the shared control-block
+    mServerHeap = new MemoryHeapBase(4096,
+            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
+    ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
+    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
+    ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
+    new(mServerCblk) surface_flinger_cblk_t;
+
+
+    // initialize EGL
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(display, NULL, NULL);
+
+    // Initialize the main display
+    // create native window to main display
+    sp<FramebufferSurface> anw = FramebufferSurface::create();
+    ANativeWindow* const window = anw.get();
+    if (!window) {
+        ALOGE("Display subsystem failed to initialize. check logs. exiting...");
+        exit(0);
+    }
+
+    // initialize the config and context
+    int format;
+    window->query(window, NATIVE_WINDOW_FORMAT, &format);
+    mEGLConfig  = selectEGLConfig(display, format);
+    mEGLContext = createGLContext(display, mEGLConfig);
+
+    // initialize our main display hardware
+    DisplayHardware* const hw = new DisplayHardware(this, 0, anw, mEGLConfig);
+    mDisplayHardwares[0] = hw;
+
+    //  initialize OpenGL ES
+    EGLSurface surface = hw->getEGLSurface();
+    initializeGL(display, surface);
 
     // start the EventThread
     mEventThread = new EventThread(this);
     mEventQueue.setEventThread(mEventThread);
 
-    /*
-     *  We're now ready to accept clients...
-     */
-
+    // We're now ready to accept clients...
     mReadyToRunBarrier.open();
 
     // start boot animation
@@ -309,6 +416,15 @@
     property_set("ctl.start", "bootanim");
 }
 
+uint32_t SurfaceFlinger::getMaxTextureSize() const {
+    return mMaxTextureSize;
+}
+
+uint32_t SurfaceFlinger::getMaxViewportDims() const {
+    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
+            mMaxViewportDims[0] : mMaxViewportDims[1];
+}
+
 // ----------------------------------------------------------------------------
 
 bool SurfaceFlinger::authenticateSurfaceTexture(
@@ -367,7 +483,7 @@
     if (display != NULL) {
         stc = new SurfaceTextureClient(display);
         result = eglCreateWindowSurface(hw.getEGLDisplay(),
-                hw.getEGLConfig(), (EGLNativeWindowType)stc.get(), NULL);
+                mEGLConfig, (EGLNativeWindowType)stc.get(), NULL);
         ALOGE_IF(result == EGL_NO_SURFACE,
                 "eglCreateWindowSurface failed (ISurfaceTexture=%p)",
                 display.get());
@@ -465,6 +581,40 @@
 void SurfaceFlinger::handleMessageRefresh() {
     handleRefresh();
 
+    if (mVisibleRegionsDirty) {
+        Region opaqueRegion;
+        Region dirtyRegion;
+        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
+        computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion);
+        mDirtyRegion.orSelf(dirtyRegion);
+
+        /*
+         *  rebuild the visible layer list per screen
+         */
+
+        // TODO: iterate through all displays
+        DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0)));
+
+        Vector< sp<LayerBase> > layersSortedByZ;
+        const size_t count = currentLayers.size();
+        for (size_t i=0 ; i<count ; i++) {
+            if (!currentLayers[i]->visibleRegion.isEmpty()) {
+                // TODO: also check that this layer is associated to this display
+                layersSortedByZ.add(currentLayers[i]);
+            }
+        }
+        hw.setVisibleLayersSortedByZ(layersSortedByZ);
+
+
+        // FIXME: mWormholeRegion needs to be calculated per screen
+        //const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: we can't keep that here
+        mWormholeRegion = Region(hw.getBounds()).subtract(
+                hw.getTransform().transform(opaqueRegion) );
+        mVisibleRegionsDirty = false;
+        invalidateHwcGeometry();
+    }
+
+
     // XXX: dirtyRegion should be per screen, we should check all of them
     if (mDirtyRegion.isEmpty()) {
         return;
@@ -515,7 +665,8 @@
             glClear(GL_COLOR_BUFFER_BIT);
             glMatrixMode(GL_MODELVIEW);
             glLoadIdentity();
-            const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+
+            const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() );
             const size_t count = layers.size();
             for (size_t i=0 ; i<count ; ++i) {
                 const sp<LayerBase>& layer(layers[i]);
@@ -546,7 +697,8 @@
 
     const DisplayHardware& hw(getDefaultDisplayHardware());
     HWComposer& hwc(hw.getHwComposer());
-    size_t numLayers = mVisibleLayersSortedByZ.size();
+    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
+    size_t numLayers = layers.size();
     const nsecs_t now = systemTime();
     mDebugInSwapBuffers = now;
 
@@ -555,7 +707,7 @@
         const HWComposer::LayerListIterator end = hwc.end();
         for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
             if (cur->getCompositionType() == HWC_OVERLAY) {
-                mVisibleLayersSortedByZ[i]->setAcquireFence(*cur);
+                layers[i]->setAcquireFence(*cur);
             } else {
                 cur->setAcquireFenceFd(-1);
             }
@@ -568,11 +720,11 @@
         HWComposer::LayerListIterator cur = hwc.begin();
         const HWComposer::LayerListIterator end = hwc.end();
         for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
-            mVisibleLayersSortedByZ[i]->onLayerDisplayed(&*cur);
+            layers[i]->onLayerDisplayed(&*cur);
         }
     } else {
         for (size_t i = 0; i < numLayers; i++) {
-            mVisibleLayersSortedByZ[i]->onLayerDisplayed(NULL);
+            layers[i]->onLayerDisplayed(NULL);
         }
     }
 
@@ -713,7 +865,7 @@
     Region aboveCoveredLayers;
     Region dirty;
 
-    bool secureFrameBuffer = false;
+    dirtyRegion.clear();
 
     size_t i = currentLayers.size();
     while (i--) {
@@ -823,14 +975,8 @@
         // Store the visible region is screen space
         layer->setVisibleRegion(visibleRegion);
         layer->setCoveredRegion(coveredRegion);
-
-        // If a secure layer is partially visible, lock-down the screen!
-        if (layer->isSecure() && !visibleRegion.isEmpty()) {
-            secureFrameBuffer = true;
-        }
     }
 
-    mSecureFrameBuffer = secureFrameBuffer;
     opaqueRegion = aboveOpaqueLayers;
 }
 
@@ -849,30 +995,7 @@
         dirtyRegion.orSelf( layer->latchBuffer(visibleRegions) );
     }
 
-    if (visibleRegions || mVisibleRegionsDirty) {
-        Region opaqueRegion;
-        computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion);
-
-        /*
-         *  rebuild the visible layer list
-         */
-
-        // XXX: mVisibleLayersSortedByZ should be per-screen
-        const size_t count = currentLayers.size();
-        mVisibleLayersSortedByZ.clear();
-        mVisibleLayersSortedByZ.setCapacity(count);
-        for (size_t i=0 ; i<count ; i++) {
-            if (!currentLayers[i]->visibleRegion.isEmpty())
-                mVisibleLayersSortedByZ.add(currentLayers[i]);
-        }
-
-        // FIXME: mWormholeRegion needs to be calculated per screen
-        const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: we can't keep that here
-        mWormholeRegion = Region(hw.getBounds()).subtract(
-                hw.getTransform().transform(opaqueRegion) );
-        mVisibleRegionsDirty = false;
-        invalidateHwcGeometry();
-    }
+    mVisibleRegionsDirty |= visibleRegions;
 
     return dirtyRegion;
 }
@@ -904,7 +1027,7 @@
     mHwWorkListDirty = false;
     HWComposer& hwc(hw.getHwComposer());
     if (hwc.initCheck() == NO_ERROR) {
-        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
+        const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
         const size_t count = currentLayers.size();
         hwc.createWorkList(count);
 
@@ -971,7 +1094,7 @@
         return;
     }
 
-    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
     size_t count = layers.size();
 
     ALOGE_IF(hwc.getNumLayers() != count,
@@ -1025,25 +1148,29 @@
          * and then, render the layers targeted at the framebuffer
          */
 
-        const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+        const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
         const size_t count = layers.size();
         const Transform& tr = hw.getTransform();
-        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
+        for (size_t i=0 ; i<count ; ++i) {
             const sp<LayerBase>& layer(layers[i]);
             const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
             if (!clip.isEmpty()) {
-                if (cur->getCompositionType() == HWC_OVERLAY) {
+                if (cur != end && cur->getCompositionType() == HWC_OVERLAY) {
                     if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
                             && layer->isOpaque()) {
                         // never clear the very first layer since we're
                         // guaranteed the FB is already cleared
                         layer->clearWithOpenGL(hw, clip);
                     }
+                    ++cur;
                     continue;
                 }
                 // render the layer
                 layer->draw(hw, clip);
             }
+            if (cur != end) {
+                ++cur;
+            }
         }
     }
 }
@@ -1741,7 +1868,7 @@
             hwc.initCheck()==NO_ERROR ? "present" : "not present",
                     (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
     result.append(buffer);
-    hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
+    hwc.dump(result, buffer, SIZE, hw.getVisibleLayersSortedByZ());
 
     /*
      * Dump gralloc state
@@ -1931,7 +2058,7 @@
     glClear(GL_COLOR_BUFFER_BIT);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
-    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
     const size_t count = layers.size();
     for (size_t i=0 ; i<count ; ++i) {
         const sp<LayerBase>& layer(layers[i]);
@@ -2428,19 +2555,27 @@
     status_t result = PERMISSION_DENIED;
 
     // only one display supported for now
-    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) {
         return BAD_VALUE;
+    }
 
-    if (!GLExtensions::getInstance().haveFramebufferObject())
+    if (!GLExtensions::getInstance().haveFramebufferObject()) {
         return INVALID_OPERATION;
+    }
 
     // get screen geometry
     const DisplayHardware& hw(getDisplayHardware(dpy));
     const uint32_t hw_w = hw.getWidth();
     const uint32_t hw_h = hw.getHeight();
 
-    if ((sw > hw_w) || (sh > hw_h))
+    // if we have secure windows on this display, never allow the screen capture
+    if (hw.getSecureLayerVisible()) {
+        return PERMISSION_DENIED;
+    }
+
+    if ((sw > hw_w) || (sh > hw_h)) {
         return BAD_VALUE;
+    }
 
     sw = (!sw) ? hw_w : sw;
     sh = (!sh) ? hw_h : sh;
@@ -2579,14 +2714,8 @@
         }
         virtual bool handler() {
             Mutex::Autolock _l(flinger->mStateLock);
-
-            // if we have secure windows, never allow the screen capture
-            if (flinger->mSecureFrameBuffer)
-                return true;
-
             result = flinger->captureScreenImplLocked(dpy,
                     heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
-
             return true;
         }
     };
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 91cc6a5..4af31fb 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -148,6 +148,8 @@
 
     GLuint getProtectedTexName() const { return mProtectedTexName; }
 
+    surface_flinger_cblk_t* getControlBlock() const;
+
 
     class MessageDestroyGLTexture : public MessageBase {
         GLuint texture;
@@ -294,6 +296,18 @@
             void        debugFlashRegions(const DisplayHardware& hw);
             void        drawWormhole() const;
 
+            uint32_t    getMaxTextureSize() const;
+            uint32_t    getMaxViewportDims() const;
+
+            static status_t selectConfigForPixelFormat(
+                    EGLDisplay dpy,
+                    EGLint const* attrs,
+                    PixelFormat format,
+                    EGLConfig* outConfig);
+            static EGLConfig selectEGLConfig(EGLDisplay disp, EGLint visualId);
+            static EGLContext createGLContext(EGLDisplay disp, EGLConfig config);
+            void initializeGL(EGLDisplay display, EGLSurface surface);
+
             void        startBootAnim();
 
             void listLayersLocked(const Vector<String16>& args, size_t& index,
@@ -331,6 +345,11 @@
                 GLuint                      mProtectedTexName;
                 nsecs_t                     mBootTime;
                 sp<EventThread>             mEventThread;
+                GLint                       mMaxViewportDims[2];
+                GLint                       mMaxTextureSize;
+                EGLContext                  mEGLContext;
+                EGLConfig                   mEGLConfig;
+
 
                 // Can only accessed from the main thread, these members
                 // don't need synchronization
@@ -342,7 +361,6 @@
                 bool                        mVisibleRegionsDirty;
                 bool                        mHwWorkListDirty;
                 int32_t                     mElectronBeamAnimationMode;
-                Vector< sp<LayerBase> >     mVisibleLayersSortedByZ;
 
 
                 // don't use a lock for these, we don't care
@@ -364,9 +382,6 @@
     mutable     Mutex                       mDestroyedLayerLock;
                 Vector<LayerBase const *>   mDestroyedLayers;
 
-   // only written in the main thread, only read in other threads
-   volatile     int32_t                     mSecureFrameBuffer;
-
 
    EGLSurface getExternalDisplaySurface() const;
    sp<SurfaceTextureClient> mExternalDisplayNativeWindow;