Eradicate DisplayID.

DisplayDevices are now keyed of the wp<IBinder> the client uses.
DisplayID has now become DisplayType which is just used to identify
physical displays (as opposed to virtual displays such as wifi displays).

Change-Id: I0c5968f2c902dcd699a7e0afacf833ff070c12ea
diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h
index 39cf090..e256e33 100644
--- a/include/gui/ISurfaceComposerClient.h
+++ b/include/gui/ISurfaceComposerClient.h
@@ -30,12 +30,6 @@
 #include <gui/ISurface.h>
 
 namespace android {
-
-// ----------------------------------------------------------------------------
-
-// TODO: Remove this declaration, it is only used internally by SurfaceFlinger.
-typedef int32_t    DisplayID;
-
 // ----------------------------------------------------------------------------
 
 class ISurfaceComposerClient : public IInterface
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index b0f2330..c28254f 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -140,9 +140,8 @@
         }
         sp<ISurface> getResult() const { return result; }
         virtual bool handler() {
-            // TODO don't require display id to create a layer
             result = flinger->createLayer(params, name, client,
-                    ISurfaceComposer::eDisplayIdMain, w, h, format, flags);
+                    w, h, format, flags);
             return true;
         }
     };
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 821a329..16e5547 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -68,12 +68,12 @@
 
 DisplayDevice::DisplayDevice(
         const sp<SurfaceFlinger>& flinger,
-        int32_t display, int32_t hwcDisplayId,
+        DisplayType type, const wp<IBinder>& displayToken,
         const sp<ANativeWindow>& nativeWindow,
         const sp<FramebufferSurface>& framebufferSurface,
         EGLConfig config)
     : mFlinger(flinger),
-      mId(display), mHwcDisplayId(hwcDisplayId),
+      mType(type), mHwcDisplayId(-1),
       mNativeWindow(nativeWindow),
       mFramebufferSurface(framebufferSurface),
       mDisplay(EGL_NO_DISPLAY),
@@ -141,7 +141,10 @@
     mPageFlipCount = 0;
 
     // external displays are always considered enabled
-    mScreenAcquired = mId >= DisplayDevice::DISPLAY_ID_COUNT;
+    mScreenAcquired = (mType >= DisplayDevice::NUM_DISPLAY_TYPES);
+
+    // get an h/w composer ID
+    mHwcDisplayId = mFlinger->allocateHwcDisplayId(mType);
 
     // initialize the display orientation transform.
     DisplayDevice::setOrientation(DisplayState::eOrientationDefault);
@@ -210,7 +213,7 @@
     }
 }
 
-Vector< sp<LayerBase> > DisplayDevice::getVisibleLayersSortedByZ() const {
+const Vector< sp<LayerBase> >& DisplayDevice::getVisibleLayersSortedByZ() const {
     return mVisibleLayersSortedByZ;
 }
 
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index ea56d90..b742b13 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -51,10 +51,12 @@
     // region in screen space
     Region undefinedRegion;
 
-    enum {
-        DISPLAY_ID_MAIN = HWC_DISPLAY_PRIMARY,
-        DISPLAY_ID_HDMI = HWC_DISPLAY_EXTERNAL,
-        DISPLAY_ID_COUNT = HWC_NUM_DISPLAY_TYPES
+    enum DisplayType {
+        DISPLAY_ID_INVALID = -1,
+        DISPLAY_PRIMARY     = HWC_DISPLAY_PRIMARY,
+        DISPLAY_EXTERNAL    = HWC_DISPLAY_EXTERNAL,
+        NUM_DISPLAY_TYPES   = HWC_NUM_DISPLAY_TYPES,
+        DISPLAY_VIRTUAL     = HWC_NUM_DISPLAY_TYPES
     };
 
     enum {
@@ -64,7 +66,7 @@
 
     DisplayDevice(
             const sp<SurfaceFlinger>& flinger,
-            int32_t dpy, int32_t hwcDisplayId,
+            DisplayType type, const wp<IBinder>& displayToken,
             const sp<ANativeWindow>& nativeWindow,
             const sp<FramebufferSurface>& framebufferSurface,
             EGLConfig config);
@@ -87,7 +89,7 @@
     EGLSurface  getEGLSurface() const;
 
     void                    setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers);
-    Vector< sp<LayerBase> > getVisibleLayersSortedByZ() const;
+    const Vector< sp<LayerBase> >& getVisibleLayersSortedByZ() const;
     bool                    getSecureLayerVisible() const;
     Region                  getDirtyRegion(bool repaintEverything) const;
 
@@ -97,8 +99,9 @@
     int                     getOrientation() const { return mOrientation; }
     const Transform&        getTransform() const { return mGlobalTransform; }
     uint32_t                getLayerStack() const { return mLayerStack; }
-    int32_t                 getDisplayId() const { return mId; }
+    int32_t                 getDisplayType() const { return mType; }
     int32_t                 getHwcDisplayId() const { return mHwcDisplayId; }
+    const wp<IBinder>&      getDisplayToken() const { return mDisplayToken; }
 
     status_t compositionComplete() const;
     
@@ -123,10 +126,6 @@
     uint32_t getPageFlipCount() const;
     void dump(String8& res) const;
 
-    inline bool operator < (const DisplayDevice& rhs) const {
-        return mId < rhs.mId;
-    }
-
 private:
     void init(EGLConfig config);
 
@@ -134,8 +133,9 @@
      *  Constants, set during initialization
      */
     sp<SurfaceFlinger> mFlinger;
-    int32_t mId;
+    DisplayType mType;
     int32_t mHwcDisplayId;
+    wp<IBinder> mDisplayToken;
 
     // ANativeWindow this display is rendering into
     sp<ANativeWindow> mNativeWindow;
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index a39b7d8..dcda67e 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -106,7 +106,7 @@
 }
 
 
-void EventThread::onVSyncReceived(int, nsecs_t timestamp) {
+void EventThread::onVSyncReceived(const wp<IBinder>&, nsecs_t timestamp) {
     Mutex::Autolock _l(mLock);
     mVSyncTimestamp = timestamp;
     mVSyncCount++;
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
index 20ea34d..c8bb312 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -76,7 +76,7 @@
     void onScreenAcquired();
 
     // called when receiving a vsync event
-    void onVSyncReceived(int display, nsecs_t timestamp);
+    void onVSyncReceived(const wp<IBinder>& display, nsecs_t timestamp);
 
     Vector< sp<EventThread::Connection> > waitForEvent(
             DisplayEventReceiver::Event* event);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 0825ec6..4c82f91 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -50,9 +50,8 @@
 
 // ---------------------------------------------------------------------------
 
-Layer::Layer(SurfaceFlinger* flinger,
-        DisplayID display, const sp<Client>& client)
-    :   LayerBaseClient(flinger, display, client),
+Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client)
+    :   LayerBaseClient(flinger, client),
         mTextureName(-1U),
         mQueuedFrames(0),
         mCurrentTransform(0),
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index d24013b..78fe321 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -50,9 +50,7 @@
 class Layer : public LayerBaseClient
 {
 public:
-            Layer(SurfaceFlinger* flinger, DisplayID display,
-                    const sp<Client>& client);
-
+            Layer(SurfaceFlinger* flinger, const sp<Client>& client);
     virtual ~Layer();
 
     virtual const char* getTypeId() const { return "Layer"; }
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 2311e6d..a2513a2 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -41,8 +41,8 @@
 
 int32_t LayerBase::sSequence = 1;
 
-LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
-    : dpy(display), contentDirty(false),
+LayerBase::LayerBase(SurfaceFlinger* flinger)
+    : contentDirty(false),
       sequence(uint32_t(android_atomic_inc(&sSequence))),
       mFlinger(flinger), mFiltering(false),
       mNeedsFiltering(false),
@@ -461,9 +461,9 @@
 
 int32_t LayerBaseClient::sIdentity = 1;
 
-LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
+LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger,
         const sp<Client>& client)
-    : LayerBase(flinger, display),
+    : LayerBase(flinger),
       mHasSurface(false),
       mClientRef(client),
       mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 6394542..c18f397 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -54,9 +54,8 @@
     static int32_t sSequence;
 
 public:
-            LayerBase(SurfaceFlinger* flinger, DisplayID display);
+            LayerBase(SurfaceFlinger* flinger);
 
-    DisplayID           dpy;
     mutable bool        contentDirty;
             // regions below are in window-manager space
             Region      visibleRegion;
@@ -293,8 +292,7 @@
 class LayerBaseClient : public LayerBase
 {
 public:
-            LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
-                        const sp<Client>& client);
+            LayerBaseClient(SurfaceFlinger* flinger, const sp<Client>& client);
 
             virtual ~LayerBaseClient();
 
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index 087d851..25caa0a 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -33,9 +33,8 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display,
-        const sp<Client>& client)
-    : LayerBaseClient(flinger, display, client)
+LayerDim::LayerDim(SurfaceFlinger* flinger, const sp<Client>& client)
+    : LayerBaseClient(flinger, client)
 {
 }
 
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index fbfb2fb..06f312d 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -32,8 +32,7 @@
 class LayerDim : public LayerBaseClient
 {
 public:    
-                LayerDim(SurfaceFlinger* flinger, DisplayID display,
-                        const sp<Client>& client);
+                LayerDim(SurfaceFlinger* flinger, const sp<Client>& client);
         virtual ~LayerDim();
 
     virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp
index 799ecdc..5c18ebd 100644
--- a/services/surfaceflinger/LayerScreenshot.cpp
+++ b/services/surfaceflinger/LayerScreenshot.cpp
@@ -34,9 +34,9 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, DisplayID display,
+LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger,
         const sp<Client>& client)
-    : LayerBaseClient(flinger, display, client),
+    : LayerBaseClient(flinger, client),
       mTextureName(0), mFlinger(flinger)
 {
 }
@@ -48,9 +48,10 @@
     }
 }
 
-status_t LayerScreenshot::captureLocked() {
+status_t LayerScreenshot::captureLocked(int32_t layerStack) {
     GLfloat u, v;
-    status_t result = mFlinger->renderScreenToTextureLocked(0, &mTextureName, &u, &v);
+    status_t result = mFlinger->renderScreenToTextureLocked(layerStack,
+            &mTextureName, &u, &v);
     if (result != NO_ERROR) {
         return result;
     }
@@ -93,7 +94,7 @@
     if (draw.flags & layer_state_t::eLayerHidden) {
         if (!(curr.flags & layer_state_t::eLayerHidden)) {
             // we're going from hidden to visible
-            status_t err = captureLocked();
+            status_t err = captureLocked(curr.layerStack);
             if (err != NO_ERROR) {
                 ALOGW("createScreenshotSurface failed (%s)", strerror(-err));
             }
diff --git a/services/surfaceflinger/LayerScreenshot.h b/services/surfaceflinger/LayerScreenshot.h
index c06c23c..7807ffc 100644
--- a/services/surfaceflinger/LayerScreenshot.h
+++ b/services/surfaceflinger/LayerScreenshot.h
@@ -35,8 +35,7 @@
     GLfloat mTexCoords[8];
     sp<SurfaceFlinger> mFlinger;
 public:    
-            LayerScreenshot(SurfaceFlinger* flinger, DisplayID display,
-                        const sp<Client>& client);
+            LayerScreenshot(SurfaceFlinger* flinger, const sp<Client>& client);
         virtual ~LayerScreenshot();
 
         status_t capture();
@@ -51,7 +50,7 @@
     virtual const char* getTypeId() const { return "LayerScreenshot"; }
 
 private:
-    status_t captureLocked();
+    status_t captureLocked(int32_t layerStack);
     void initTexture(GLfloat u, GLfloat v);
 };
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ed687e3..09ade12 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -155,24 +155,6 @@
     return bclient;
 }
 
-int32_t SurfaceFlinger::chooseNewDisplayIdLocked() const
-{
-    int32_t id = DisplayDevice::DISPLAY_ID_COUNT - 1;
-    bool available;
-    do {
-        id++;
-        available = true;
-        for (size_t i = 0; i < mCurrentState.displays.size(); i++) {
-            const DisplayDeviceState& dds(mCurrentState.displays.valueAt(i));
-            if (dds.id == id) {
-                available = false;
-                break;
-            }
-        }
-    } while (!available);
-    return id;
-}
-
 sp<IBinder> SurfaceFlinger::createDisplay()
 {
     class DisplayToken : public BBinder {
@@ -192,15 +174,14 @@
     sp<BBinder> token = new DisplayToken(this);
 
     Mutex::Autolock _l(mStateLock);
-    int32_t id = chooseNewDisplayIdLocked();
-    DisplayDeviceState info(id);
+    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
     mCurrentState.displays.add(token, info);
 
     return token;
 }
 
 sp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
-    if (uint32_t(id) >= DisplayDevice::DISPLAY_ID_COUNT) {
+    if (uint32_t(id) >= DisplayDevice::NUM_DISPLAY_TYPES) {
         ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
         return NULL;
     }
@@ -416,14 +397,16 @@
 
     // initialize our main display hardware
 
-    for (size_t i=0 ; i<DisplayDevice::DISPLAY_ID_COUNT ; i++) {
+    for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
         mDefaultDisplays[i] = new BBinder();
-        mCurrentState.displays.add(mDefaultDisplays[i], DisplayDeviceState(i));
+        mCurrentState.displays.add(mDefaultDisplays[i],
+                DisplayDeviceState((DisplayDevice::DisplayType)i));
     }
     sp<DisplayDevice> hw = new DisplayDevice(this,
-            DisplayDevice::DISPLAY_ID_MAIN, HWC_DISPLAY_PRIMARY,
+            DisplayDevice::DISPLAY_PRIMARY,
+            mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY],
             anw, fbs, mEGLConfig);
-    mDisplays.add(hw->getDisplayId(), hw);
+    mDisplays.add(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], hw);
 
     //  initialize OpenGL ES
     EGLSurface surface = hw->getEGLSurface();
@@ -453,6 +436,11 @@
     return NO_ERROR;
 }
 
+int32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
+    return (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) ?
+            type : mHwc->allocateDisplayId();
+}
+
 void SurfaceFlinger::startBootAnim() {
     // start boot animation
     property_set("service.bootanim.exit", "0");
@@ -637,8 +625,12 @@
     return true;
 }
 
-void SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) {
-    mEventThread->onVSyncReceived(dpy, timestamp);
+void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
+    if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) {
+        // we should only receive DisplayDevice::DisplayType from the vsync callback
+        const wp<IBinder>& token(mDefaultDisplays[type]);
+        mEventThread->onVSyncReceived(token, timestamp);
+    }
 }
 
 void SurfaceFlinger::eventControl(int event, int enabled) {
@@ -718,7 +710,7 @@
                 }
                 hw->compositionComplete();
                 // FIXME
-                if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) {
+                if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
                     eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
                 }
             }
@@ -863,8 +855,7 @@
         // FIXME: EGL spec says:
         //   "surface must be bound to the calling thread's current context,
         //    for the current rendering API."
-        DisplayDevice::makeCurrent(
-                getDisplayDevice(DisplayDevice::DISPLAY_ID_MAIN), mEGLContext);
+        DisplayDevice::makeCurrent(getDefaultDisplayDevice(), mEGLContext);
         hwc.commit();
     }
 
@@ -958,40 +949,36 @@
                 const ssize_t j = curr.indexOfKey(draw.keyAt(i));
                 if (j < 0) {
                     // in drawing state but not in current state
-                    if (draw[i].id != DisplayDevice::DISPLAY_ID_MAIN) {
-                        mDisplays.removeItem(draw[i].id);
+                    if (!draw[i].isMainDisplay()) {
+                        mDisplays.removeItem(draw.keyAt(i));
                     } else {
                         ALOGW("trying to remove the main display");
                     }
                 } else {
                     // this display is in both lists. see if something changed.
                     const DisplayDeviceState& state(curr[j]);
+                    const wp<IBinder>& display(curr.keyAt(j));
                     if (state.surface->asBinder() != draw[i].surface->asBinder()) {
                         // changing the surface is like destroying and
                         // recreating the DisplayDevice
-                        const int32_t hwcDisplayId =
-                            (uint32_t(state.id) < DisplayDevice::DISPLAY_ID_COUNT) ?
-                                state.id : getHwComposer().allocateDisplayId();
-
                         sp<SurfaceTextureClient> stc(
                                 new SurfaceTextureClient(state.surface));
-
                         sp<DisplayDevice> disp = new DisplayDevice(this,
-                            state.id, hwcDisplayId, stc, 0, mEGLConfig);
+                            state.type, display, stc, NULL, mEGLConfig);
 
                         disp->setLayerStack(state.layerStack);
                         disp->setOrientation(state.orientation);
                         // TODO: take viewport and frame into account
-                        mDisplays.replaceValueFor(state.id, disp);
+                        mDisplays.replaceValueFor(display, disp);
                     }
                     if (state.layerStack != draw[i].layerStack) {
-                        const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
+                        const sp<DisplayDevice>& disp(getDisplayDevice(display));
                         disp->setLayerStack(state.layerStack);
                     }
                     if (state.orientation != draw[i].orientation ||
                         state.viewport != draw[i].viewport ||
                         state.frame != draw[i].frame) {
-                        const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
+                        const sp<DisplayDevice>& disp(getDisplayDevice(display));
                         disp->setOrientation(state.orientation);
                         // TODO: take viewport and frame into account
                     }
@@ -1003,15 +990,12 @@
             for (size_t i=0 ; i<cc ; i++) {
                 if (draw.indexOfKey(curr.keyAt(i)) < 0) {
                     const DisplayDeviceState& state(curr[i]);
-                    const int32_t hwcDisplayId =
-                        (uint32_t(state.id) < DisplayDevice::DISPLAY_ID_COUNT) ?
-                            state.id : getHwComposer().allocateDisplayId();
-
                     sp<SurfaceTextureClient> stc(
                             new SurfaceTextureClient(state.surface));
+                    const wp<IBinder>& display(curr.keyAt(i));
                     sp<DisplayDevice> disp = new DisplayDevice(this,
-                        state.id, hwcDisplayId, stc, 0, mEGLConfig);
-                    mDisplays.add(state.id, disp);
+                        state.type, display, stc, 0, mEGLConfig);
+                    mDisplays.add(display, disp);
                 }
             }
         }
@@ -1262,7 +1246,7 @@
     // GL composition and only on those.
     // however, currently hwc.commit() already does that for the main
     // display and never for the other ones
-    if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) {
+    if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
         // FIXME: EGL spec says:
         //   "surface must be bound to the calling thread's current context,
         //    for the current rendering API."
@@ -1485,7 +1469,7 @@
 {
     uint32_t flags = 0;
     DisplayDeviceState& disp(mCurrentState.displays.editValueFor(s.token));
-    if (disp.id >= 0) {
+    if (disp.isValid()) {
         const uint32_t what = s.what;
         if (what & DisplayState::eSurfaceChanged) {
             if (disp.surface->asBinder() != s.surface->asBinder()) {
@@ -1588,7 +1572,7 @@
         ISurfaceComposerClient::surface_data_t* params,
         const String8& name,
         const sp<Client>& client,
-        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
+       uint32_t w, uint32_t h, PixelFormat format,
         uint32_t flags)
 {
     sp<LayerBaseClient> layer;
@@ -1603,14 +1587,14 @@
     //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
     switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
         case ISurfaceComposerClient::eFXSurfaceNormal:
-            layer = createNormalLayer(client, d, w, h, flags, format);
+            layer = createNormalLayer(client, w, h, flags, format);
             break;
         case ISurfaceComposerClient::eFXSurfaceBlur:
         case ISurfaceComposerClient::eFXSurfaceDim:
-            layer = createDimLayer(client, d, w, h, flags);
+            layer = createDimLayer(client, w, h, flags);
             break;
         case ISurfaceComposerClient::eFXSurfaceScreenshot:
-            layer = createScreenshotLayer(client, d, w, h, flags);
+            layer = createScreenshotLayer(client, w, h, flags);
             break;
     }
 
@@ -1630,7 +1614,7 @@
 }
 
 sp<Layer> SurfaceFlinger::createNormalLayer(
-        const sp<Client>& client, DisplayID display,
+        const sp<Client>& client,
         uint32_t w, uint32_t h, uint32_t flags,
         PixelFormat& format)
 {
@@ -1654,7 +1638,7 @@
         format = PIXEL_FORMAT_RGBA_8888;
 #endif
 
-    sp<Layer> layer = new Layer(this, display, client);
+    sp<Layer> layer = new Layer(this, client);
     status_t err = layer->setBuffers(w, h, format, flags);
     if (CC_LIKELY(err != NO_ERROR)) {
         ALOGE("createNormalLayer() failed (%s)", strerror(-err));
@@ -1664,18 +1648,18 @@
 }
 
 sp<LayerDim> SurfaceFlinger::createDimLayer(
-        const sp<Client>& client, DisplayID display,
+        const sp<Client>& client,
         uint32_t w, uint32_t h, uint32_t flags)
 {
-    sp<LayerDim> layer = new LayerDim(this, display, client);
+    sp<LayerDim> layer = new LayerDim(this, client);
     return layer;
 }
 
 sp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
-        const sp<Client>& client, DisplayID display,
+        const sp<Client>& client,
         uint32_t w, uint32_t h, uint32_t flags)
 {
-    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
+    sp<LayerScreenshot> layer = new LayerScreenshot(this, client);
     return layer;
 }
 
@@ -1733,7 +1717,7 @@
     Vector<DisplayState> displays;
     DisplayState d;
     d.what = DisplayState::eOrientationChanged;
-    d.token = mDefaultDisplays[DisplayDevice::DISPLAY_ID_MAIN];
+    d.token = mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY];
     d.orientation = DisplayState::eOrientationDefault;
     displays.add(d);
     setTransactionState(state, displays, 0);
@@ -1973,7 +1957,7 @@
                 "   id=%x, layerStack=%u, (%4dx%4d), orient=%2d, tr=%08x, "
                 "flips=%u, secure=%d, numLayers=%u\n",
                 dpy,
-                hw->getDisplayId(), hw->getLayerStack(),
+                hw->getDisplayType(), hw->getLayerStack(),
                 hw->getWidth(), hw->getHeight(),
                 hw->getOrientation(), hw->getTransform().getType(),
                 hw->getPageFlipCount(),
@@ -2169,14 +2153,14 @@
 
 // ---------------------------------------------------------------------------
 
-status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
+status_t SurfaceFlinger::renderScreenToTexture(uint32_t layerStack,
         GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
 {
     Mutex::Autolock _l(mStateLock);
-    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
+    return renderScreenToTextureLocked(layerStack, textureName, uOut, vOut);
 }
 
-status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
+status_t SurfaceFlinger::renderScreenToTextureLocked(uint32_t layerStack,
         GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
 {
     ATRACE_CALL();
@@ -2185,7 +2169,8 @@
         return INVALID_OPERATION;
 
     // get screen geometry
-    sp<const DisplayDevice> hw(getDisplayDevice(dpy));
+    // FIXME: figure out what it means to have a screenshot texture w/ multi-display
+    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
     const uint32_t hw_w = hw->getWidth();
     const uint32_t hw_h = hw->getHeight();
     GLfloat u = 1;
@@ -2254,17 +2239,12 @@
 
     status_t result = PERMISSION_DENIED;
 
-    const DisplayDeviceState& disp(mDrawingState.displays.valueFor(display));
-    if (CC_UNLIKELY(disp.id < 0)) {
-        return BAD_VALUE;
-    }
-
     if (!GLExtensions::getInstance().haveFramebufferObject()) {
         return INVALID_OPERATION;
     }
 
     // get screen geometry
-    sp<const DisplayDevice> hw(getDisplayDevice(disp.id));
+    sp<const DisplayDevice> hw(getDisplayDevice(display));
     const uint32_t hw_w = hw->getWidth();
     const uint32_t hw_h = hw->getHeight();
 
@@ -2317,19 +2297,15 @@
         glClearColor(0,0,0,1);
         glClear(GL_COLOR_BUFFER_BIT);
 
-        // TODO: filter the layers that are drawn based on the layer stack of the display.
-        const LayerVector& layers(mDrawingState.layersSortedByZ);
+        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]);
-            const uint32_t flags = layer->drawingState().flags;
-            if (!(flags & layer_state_t::eLayerHidden)) {
-                const uint32_t z = layer->drawingState().z;
-                if (z >= minLayerZ && z <= maxLayerZ) {
-                    if (filtering) layer->setFiltering(true);
-                    layer->draw(hw);
-                    if (filtering) layer->setFiltering(false);
-                }
+            const uint32_t z = layer->drawingState().z;
+            if (z >= minLayerZ && z <= maxLayerZ) {
+                if (filtering) layer->setFiltering(true);
+                layer->draw(hw);
+                if (filtering) layer->setFiltering(false);
             }
         }
 
@@ -2465,11 +2441,12 @@
 
 // ---------------------------------------------------------------------------
 
-SurfaceFlinger::DisplayDeviceState::DisplayDeviceState() : id(-1) {
+SurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
+    : type(DisplayDevice::DISPLAY_ID_INVALID) {
 }
 
-SurfaceFlinger::DisplayDeviceState::DisplayDeviceState(int32_t id)
-    : id(id), layerStack(0), orientation(0) {
+SurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
+    : type(type), layerStack(0), orientation(0) {
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 653a631..f0af3d6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -113,21 +113,23 @@
     void repaintEverything();
 
     // renders content on given display to a texture. thread-safe version.
-    status_t renderScreenToTexture(DisplayID dpy, GLuint* textureName,
+    status_t renderScreenToTexture(uint32_t layerStack, GLuint* textureName,
         GLfloat* uOut, GLfloat* vOut);
 
     // renders content on given display to a texture, w/o acquiring main lock
-    status_t renderScreenToTextureLocked(DisplayID dpy, GLuint* textureName,
+    status_t renderScreenToTextureLocked(uint32_t layerStack, GLuint* textureName,
         GLfloat* uOut, GLfloat* vOut);
 
     // returns the default Display
     sp<const DisplayDevice> getDefaultDisplayDevice() const {
-        return getDisplayDevice(DisplayDevice::DISPLAY_ID_MAIN);
+        return getDisplayDevice(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY]);
     }
 
     // utility function to delete a texture on the main thread
     void deleteTextureAsync(GLuint texture);
 
+    // allocate a h/w composer display id
+    int32_t allocateHwcDisplayId(DisplayDevice::DisplayType type);
 
     // enable/disable h/w composer event
     // TODO: this should be made accessible only to EventThread
@@ -161,8 +163,10 @@
 
     struct DisplayDeviceState {
         DisplayDeviceState();
-        DisplayDeviceState(int32_t id);
-        int32_t id;
+        DisplayDeviceState(DisplayDevice::DisplayType type);
+        bool isValid() const { return type >= 0; }
+        bool isMainDisplay() const { return type == DisplayDevice::DISPLAY_PRIMARY; }
+        DisplayDevice::DisplayType type;
         sp<ISurfaceTexture> surface;
         uint32_t layerStack;
         Rect viewport;
@@ -221,7 +225,7 @@
     /* ------------------------------------------------------------------------
      * HWComposer::EventHandler interface
      */
-    virtual void onVSyncReceived(int dpy, nsecs_t timestamp);
+    virtual void onVSyncReceived(int type, nsecs_t timestamp);
 
     /* ------------------------------------------------------------------------
      * Message handling
@@ -265,17 +269,17 @@
      * Layer management
      */
     sp<ISurface> createLayer(ISurfaceComposerClient::surface_data_t* params,
-        const String8& name, const sp<Client>& client, DisplayID display,
-        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
+            const String8& name, const sp<Client>& client,
+            uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
 
-    sp<Layer> createNormalLayer(const sp<Client>& client, DisplayID display,
-        uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format);
+    sp<Layer> createNormalLayer(const sp<Client>& client,
+            uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format);
 
-    sp<LayerDim> createDimLayer(const sp<Client>& client, DisplayID display,
-        uint32_t w, uint32_t h, uint32_t flags);
+    sp<LayerDim> createDimLayer(const sp<Client>& client,
+            uint32_t w, uint32_t h, uint32_t flags);
 
     sp<LayerScreenshot> createScreenshotLayer(const sp<Client>& client,
-        DisplayID display, uint32_t w, uint32_t h, uint32_t flags);
+            uint32_t w, uint32_t h, uint32_t flags);
 
     // called in response to the window-manager calling
     // ISurfaceComposerClient::destroySurface()
@@ -326,10 +330,10 @@
     // called when starting, or restarting after system_server death
     void initializeDisplays();
 
-    sp<const DisplayDevice> getDisplayDevice(DisplayID dpy) const {
+    sp<const DisplayDevice> getDisplayDevice(const wp<IBinder>& dpy) const {
         return mDisplays.valueFor(dpy);
     }
-    const sp<DisplayDevice>& getDisplayDevice(DisplayID dpy) {
+    const sp<DisplayDevice>& getDisplayDevice(const wp<IBinder>& dpy) {
         return mDisplays.valueFor(dpy);
     }
 
@@ -371,7 +375,7 @@
     /* ------------------------------------------------------------------------
      * Display management
      */
-    int32_t chooseNewDisplayIdLocked() const;
+
 
     /* ------------------------------------------------------------------------
      * Debugging & dumpsys
@@ -413,14 +417,14 @@
     EGLContext mEGLContext;
     EGLConfig mEGLConfig;
     EGLDisplay mEGLDisplay;
-    sp<IBinder> mDefaultDisplays[DisplayDevice::DISPLAY_ID_COUNT];
+    sp<IBinder> mDefaultDisplays[DisplayDevice::NUM_DISPLAY_TYPES];
 
     // Can only accessed from the main thread, these members
     // don't need synchronization
     State mDrawingState;
     bool mVisibleRegionsDirty;
     bool mHwWorkListDirty;
-    DefaultKeyedVector<int32_t, sp<DisplayDevice> > mDisplays;
+    DefaultKeyedVector< wp<IBinder>, sp<DisplayDevice> > mDisplays;
 
     // don't use a lock for these, we don't care
     int mDebugRegion;