turn DisplayDevice into a reference-counted object

it's safer this way because this object owns an
EGLSurface which cannot be easily reference-counted.

it also gives us the ability to sub-class it, which
we might want to do soon.

Change-Id: I07358bb052dc5a13b4f2196b2c2b6e6e94c4bb4f
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 822b2b5..175f808 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -97,14 +97,6 @@
  *
  */
 
-DisplayDevice::DisplayDevice()
-    : mId(0),
-      mDisplay(EGL_NO_DISPLAY),
-      mSurface(EGL_NO_SURFACE),
-      mContext(EGL_NO_CONTEXT)
-{
-}
-
 DisplayDevice::DisplayDevice(
         const sp<SurfaceFlinger>& flinger,
         int display,
@@ -130,12 +122,6 @@
 }
 
 DisplayDevice::~DisplayDevice() {
-    // DO NOT call terminate() from here, because we create
-    // temporaries of this class (on the stack typically), and we don't
-    // want to destroy the EGLSurface in that case
-}
-
-void DisplayDevice::terminate() {
     if (mSurface != EGL_NO_SURFACE) {
         eglDestroySurface(mDisplay, mSurface);
         mSurface = EGL_NO_SURFACE;
@@ -297,11 +283,11 @@
     }
 }
 
-void DisplayDevice::makeCurrent(const DisplayDevice& hw, EGLContext ctx) {
+void DisplayDevice::makeCurrent(const sp<const DisplayDevice>& hw, EGLContext ctx) {
     EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
-    if (sur != hw.mSurface) {
+    if (sur != hw->mSurface) {
         EGLDisplay dpy = eglGetCurrentDisplay();
-        eglMakeCurrent(dpy, hw.mSurface, hw.mSurface, ctx);
+        eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx);
     }
 }
 
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 4afca58..9bcb6fd 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -39,7 +39,7 @@
 class LayerBase;
 class SurfaceFlinger;
 
-class DisplayDevice
+class DisplayDevice : public virtual RefBase
 {
 public:
     // region in layer-stack space
@@ -59,19 +59,13 @@
         SWAP_RECTANGLE  = 0x00080000,
     };
 
-    DisplayDevice();
-
     DisplayDevice(
             const sp<SurfaceFlinger>& flinger,
             int dpy,
             const sp<ANativeWindow>& surface,
             EGLConfig config);
 
-    ~DisplayDevice();
-
-    // must be called when this object is no longer needed. this will
-    // render the associated EGLSurface invalid.
-    void terminate();
+    virtual ~DisplayDevice();
 
     // whether this is a valid object. An invalid DisplayDevice is returned
     // when an non existing id is requested
@@ -107,7 +101,7 @@
     }
     inline Rect bounds() const { return getBounds(); }
 
-    static void makeCurrent(const DisplayDevice& hw, EGLContext ctx);
+    static void makeCurrent(const sp<const DisplayDevice>& hw, EGLContext ctx);
 
     /* ------------------------------------------------------------------------
      * blank / unplank management
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index f72000f..90e5d9a 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -71,7 +71,7 @@
     glGenTextures(1, &mTextureName);
 }
 
-void Layer::onLayerDisplayed(const DisplayDevice& hw,
+void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
         HWComposer::HWCLayerInterface* layer) {
     if (layer) {
         mSurfaceTexture->setReleaseFence(layer->getAndResetReleaseFenceFd());
@@ -237,7 +237,7 @@
 }
 
 void Layer::setGeometry(
-        const DisplayDevice& hw,
+    const sp<const DisplayDevice>& hw,
         HWComposer::HWCLayerInterface& layer)
 {
     LayerBaseClient::setGeometry(hw, layer);
@@ -260,7 +260,7 @@
      */
 
     const Transform bufferOrientation(mCurrentTransform);
-    const Transform tr(hw.getTransform() * s.transform * bufferOrientation);
+    const Transform tr(hw->getTransform() * s.transform * bufferOrientation);
 
     // this gives us only the "orientation" component of the transform
     const uint32_t finalTransform = tr.getOrientation();
@@ -274,7 +274,7 @@
     layer.setCrop(computeBufferCrop());
 }
 
-void Layer::setPerFrameData(const DisplayDevice& hw,
+void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
         HWComposer::HWCLayerInterface& layer) {
     const sp<GraphicBuffer>& buffer(mActiveBuffer);
     // NOTE: buffer can be NULL if the client never drew into this
@@ -282,7 +282,7 @@
     layer.setBuffer(buffer);
 }
 
-void Layer::setAcquireFence(const DisplayDevice& hw,
+void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
         HWComposer::HWCLayerInterface& layer) {
     int fenceFd = -1;
 
@@ -301,7 +301,7 @@
     layer.setAcquireFenceFd(fenceFd);
 }
 
-void Layer::onDraw(const DisplayDevice& hw, const Region& clip) const
+void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
 {
     ATRACE_CALL();
 
@@ -323,7 +323,7 @@
             const sp<LayerBase>& layer(drawingLayers[i]);
             if (layer.get() == static_cast<LayerBase const*>(this))
                 break;
-            under.orSelf( hw.getTransform().transform(layer->visibleRegion) );
+            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
         }
         // if not everything below us is covered, we plug the holes!
         Region holes(clip.subtract(under));
@@ -728,7 +728,6 @@
 {
     LayerBaseClient::dumpStats(result, buffer, SIZE);
     const size_t o = mFrameLatencyOffset;
-    const DisplayDevice& hw(mFlinger->getDefaultDisplayDevice());
     const nsecs_t period = mFlinger->getHwComposer().getRefreshPeriod();
     result.appendFormat("%lld\n", period);
     for (size_t i=0 ; i<128 ; i++) {
@@ -769,8 +768,8 @@
         // apply to all displays.
         // This is why we use the default display here. This is not an
         // oversight.
-        const DisplayDevice& hw(mFlinger->getDefaultDisplayDevice());
-        const Transform& planeTransform(hw.getTransform());
+        sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
+        const Transform& planeTransform(hw->getTransform());
         orientation = planeTransform.getOrientation();
         if (orientation & Transform::ROT_INVALID) {
             orientation = 0;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 5e55887..d24013b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -64,18 +64,18 @@
     bool isFixedSize() const;
 
     // LayerBase interface
-    virtual void setGeometry(const DisplayDevice& hw,
+    virtual void setGeometry(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface& layer);
-    virtual void setPerFrameData(const DisplayDevice& hw,
+    virtual void setPerFrameData(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface& layer);
-    virtual void setAcquireFence(const DisplayDevice& hw,
+    virtual void setAcquireFence(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface& layer);
-    virtual void onLayerDisplayed(const DisplayDevice& hw,
+    virtual void onLayerDisplayed(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface* layer);
     virtual bool onPreComposition();
     virtual void onPostComposition();
 
-    virtual void onDraw(const DisplayDevice& hw, const Region& clip) const;
+    virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
     virtual uint32_t doTransaction(uint32_t transactionFlags);
     virtual Region latchBuffer(bool& recomputeVisibleRegions);
     virtual bool isOpaque() const;
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index f1bf984..e1477a9 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -223,11 +223,11 @@
     return flags;
 }
 
-void LayerBase::computeGeometry(const DisplayDevice& hw, LayerMesh* mesh) const
+void LayerBase::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
 {
     const Layer::State& s(drawingState());
-    const Transform tr(hw.getTransform() * s.transform);
-    const uint32_t hw_h = hw.getHeight();
+    const Transform tr(hw->getTransform() * s.transform);
+    const uint32_t hw_h = hw->getHeight();
     const Rect& crop(s.active.crop);
     Rect win(s.active.w, s.active.h);
     if (!crop.isEmpty()) {
@@ -260,7 +260,7 @@
 }
 
 void LayerBase::setGeometry(
-        const DisplayDevice& hw,
+    const sp<const DisplayDevice>& hw,
         HWComposer::HWCLayerInterface& layer)
 {
     layer.setDefaultState();
@@ -281,7 +281,7 @@
                 HWC_BLENDING_COVERAGE);
     }
 
-    const Transform& tr = hw.getTransform();
+    const Transform& tr = hw->getTransform();
     Rect transformedBounds(computeBounds());
     transformedBounds = tr.transform(transformedBounds);
 
@@ -291,12 +291,12 @@
     layer.setVisibleRegionScreen(tr.transform(visibleRegion));
 }
 
-void LayerBase::setPerFrameData(const DisplayDevice& hw,
+void LayerBase::setPerFrameData(const sp<const DisplayDevice>& hw,
         HWComposer::HWCLayerInterface& layer) {
     layer.setBuffer(0);
 }
 
-void LayerBase::setAcquireFence(const DisplayDevice& hw,
+void LayerBase::setAcquireFence(const sp<const DisplayDevice>& hw,
         HWComposer::HWCLayerInterface& layer) {
     layer.setAcquireFenceFd(-1);
 }
@@ -311,20 +311,20 @@
     return mFiltering;
 }
 
-void LayerBase::draw(const DisplayDevice& hw, const Region& clip) const
+void LayerBase::draw(const sp<const DisplayDevice>& hw, const Region& clip) const
 {
     onDraw(hw, clip);
 }
 
-void LayerBase::draw(const DisplayDevice& hw)
+void LayerBase::draw(const sp<const DisplayDevice>& hw)
 {
-    onDraw( hw, Region(hw.bounds()) );
+    onDraw( hw, Region(hw->bounds()) );
 }
 
-void LayerBase::clearWithOpenGL(const DisplayDevice& hw, const Region& clip,
+void LayerBase::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
         GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
 {
-    const uint32_t fbHeight = hw.getHeight();
+    const uint32_t fbHeight = hw->getHeight();
     glColor4f(red,green,blue,alpha);
 
     glDisable(GL_TEXTURE_EXTERNAL_OES);
@@ -338,14 +338,14 @@
     glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
 }
 
-void LayerBase::clearWithOpenGL(const DisplayDevice& hw, const Region& clip) const
+void LayerBase::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const
 {
     clearWithOpenGL(hw, clip, 0,0,0,0);
 }
 
-void LayerBase::drawWithOpenGL(const DisplayDevice& hw, const Region& clip) const
+void LayerBase::drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const
 {
-    const uint32_t fbHeight = hw.getHeight();
+    const uint32_t fbHeight = hw->getHeight();
     const State& s(drawingState());
 
     GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 663a864..6394542 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -123,7 +123,7 @@
             uint32_t getTransactionFlags(uint32_t flags);
             uint32_t setTransactionFlags(uint32_t flags);
 
-            void computeGeometry(const DisplayDevice& hw, LayerMesh* mesh) const;
+            void computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const;
             Rect computeBounds() const;
 
 
@@ -132,11 +132,11 @@
 
     virtual const char* getTypeId() const { return "LayerBase"; }
 
-    virtual void setGeometry(const DisplayDevice& hw,
+    virtual void setGeometry(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface& layer);
-    virtual void setPerFrameData(const DisplayDevice& hw,
+    virtual void setPerFrameData(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface& layer);
-    virtual void setAcquireFence(const DisplayDevice& hw,
+    virtual void setAcquireFence(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface& layer);
 
     /**
@@ -145,13 +145,13 @@
      * Typically this method is not overridden, instead implement onDraw()
      * to perform the actual drawing.  
      */
-    virtual void draw(const DisplayDevice& hw, const Region& clip) const;
-    virtual void draw(const DisplayDevice& hw);
+    virtual void draw(const sp<const DisplayDevice>& hw, const Region& clip) const;
+    virtual void draw(const sp<const DisplayDevice>& hw);
     
     /**
      * onDraw - draws the surface.
      */
-    virtual void onDraw(const DisplayDevice& hw, const Region& clip) const = 0;
+    virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const = 0;
     
     /**
      * initStates - called just after construction
@@ -218,7 +218,7 @@
 
     /** called after page-flip
      */
-    virtual void onLayerDisplayed(const DisplayDevice& hw,
+    virtual void onLayerDisplayed(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface* layer) { }
 
     /** called before composition.
@@ -247,15 +247,15 @@
     inline  const State&    currentState() const    { return mCurrentState; }
     inline  State&          currentState()          { return mCurrentState; }
 
-    void clearWithOpenGL(const DisplayDevice& hw, const Region& clip) const;
+    void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
 
     void setFiltering(bool filtering);
     bool getFiltering() const;
 
 protected:
-          void clearWithOpenGL(const DisplayDevice& hw, const Region& clip,
+          void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
                   GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const;
-          void drawWithOpenGL(const DisplayDevice& hw, const Region& clip) const;
+          void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
 
                 sp<SurfaceFlinger> mFlinger;
 
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index aef37b1..087d851 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -43,12 +43,12 @@
 {
 }
 
-void LayerDim::onDraw(const DisplayDevice& hw, const Region& clip) const
+void LayerDim::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
 {
     const State& s(drawingState());
     if (s.alpha>0) {
         const GLfloat alpha = s.alpha/255.0f;
-        const uint32_t fbHeight = hw.getHeight();
+        const uint32_t fbHeight = hw->getHeight();
         glDisable(GL_TEXTURE_EXTERNAL_OES);
         glDisable(GL_TEXTURE_2D);
 
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index a0ec593..fbfb2fb 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -36,7 +36,7 @@
                         const sp<Client>& client);
         virtual ~LayerDim();
 
-    virtual void onDraw(const DisplayDevice& hw, const Region& clip) const;
+    virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
     virtual bool isOpaque() const         { return false; }
     virtual bool isSecure() const         { return false; }
     virtual bool isProtectedByApp() const { return false; }
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp
index 280d85f..da2de76 100644
--- a/services/surfaceflinger/LayerScreenshot.cpp
+++ b/services/surfaceflinger/LayerScreenshot.cpp
@@ -108,12 +108,12 @@
     return LayerBaseClient::doTransaction(flags);
 }
 
-void LayerScreenshot::onDraw(const DisplayDevice& hw, const Region& clip) const
+void LayerScreenshot::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
 {
     const State& s(drawingState());
     if (s.alpha>0) {
         const GLfloat alpha = s.alpha/255.0f;
-        const uint32_t fbHeight = hw.getHeight();
+        const uint32_t fbHeight = hw->getHeight();
 
         if (s.alpha == 0xFF) {
             glDisable(GL_BLEND);
diff --git a/services/surfaceflinger/LayerScreenshot.h b/services/surfaceflinger/LayerScreenshot.h
index 64c0281..c06c23c 100644
--- a/services/surfaceflinger/LayerScreenshot.h
+++ b/services/surfaceflinger/LayerScreenshot.h
@@ -43,7 +43,7 @@
 
     virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
     virtual uint32_t doTransaction(uint32_t flags);
-    virtual void onDraw(const DisplayDevice& hw, const Region& clip) const;
+    virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
     virtual bool isOpaque() const         { return false; }
     virtual bool isSecure() const         { return false; }
     virtual bool isProtectedByApp() const { return false; }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3aba3db..1269f3b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -366,11 +366,11 @@
 
     // initialize our main display hardware
     mCurrentState.displays.add(DisplayDevice::DISPLAY_ID_MAIN, DisplayDeviceState());
-    DisplayDevice hw(this, DisplayDevice::DISPLAY_ID_MAIN, anw, mEGLConfig);
+    sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_ID_MAIN, anw, mEGLConfig);
     mDisplays.add(DisplayDevice::DISPLAY_ID_MAIN, hw);
 
     //  initialize OpenGL ES
-    EGLSurface surface = hw.getEGLSurface();
+    EGLSurface surface = hw->getEGLSurface();
     initializeGL(mEGLDisplay, surface);
 
     // start the EventThread
@@ -455,16 +455,16 @@
     if (uint32_t(dpy) >= 2) {
         return BAD_INDEX;
     }
-    const DisplayDevice& hw(getDefaultDisplayDevice());
-    info->w = hw.getWidth();
-    info->h = hw.getHeight();
-    info->xdpi = hw.getDpiX();
-    info->ydpi = hw.getDpiY();
+    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+    info->w = hw->getWidth();
+    info->h = hw->getHeight();
+    info->xdpi = hw->getDpiX();
+    info->ydpi = hw->getDpiY();
     info->fps = float(1e9 / getHwComposer().getRefreshPeriod());
-    info->density = hw.getDensity();
-    info->orientation = hw.getOrientation();
+    info->density = hw->getDensity();
+    info->orientation = hw->getOrientation();
     // TODO: this needs to go away (currently needed only by webkit)
-    getPixelFormatInfo(hw.getFormat(), &info->pixelFormatInfo);
+    getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
     return NO_ERROR;
 }
 
@@ -475,7 +475,6 @@
 }
 
 void SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) {
-    const DisplayDevice& hw(getDefaultDisplayDevice());
     EGLSurface result = EGL_NO_SURFACE;
     EGLSurface old_surface = EGL_NO_SURFACE;
     sp<SurfaceTextureClient> stc;
@@ -593,26 +592,26 @@
 
         const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
         for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-            DisplayDevice& hw(mDisplays.editValueAt(dpy));
+            const sp<DisplayDevice>& hw(mDisplays[dpy]);
             Region opaqueRegion;
             Region dirtyRegion;
             computeVisibleRegions(currentLayers,
-                    hw.getLayerStack(), dirtyRegion, opaqueRegion);
-            hw.dirtyRegion.orSelf(dirtyRegion);
+                    hw->getLayerStack(), dirtyRegion, opaqueRegion);
+            hw->dirtyRegion.orSelf(dirtyRegion);
 
             Vector< sp<LayerBase> > layersSortedByZ;
             const size_t count = currentLayers.size();
             for (size_t i=0 ; i<count ; i++) {
                 const Layer::State& s(currentLayers[i]->drawingState());
-                if (s.layerStack == hw.getLayerStack()) {
+                if (s.layerStack == hw->getLayerStack()) {
                     if (!currentLayers[i]->visibleRegion.isEmpty()) {
                         layersSortedByZ.add(currentLayers[i]);
                     }
                 }
             }
-            hw.setVisibleLayersSortedByZ(layersSortedByZ);
-            hw.undefinedRegion.set(hw.getBounds());
-            hw.undefinedRegion.subtractSelf(hw.getTransform().transform(opaqueRegion));
+            hw->setVisibleLayersSortedByZ(layersSortedByZ);
+            hw->undefinedRegion.set(hw->getBounds());
+            hw->undefinedRegion.subtractSelf(hw->getTransform().transform(opaqueRegion));
         }
     }
 
@@ -622,8 +621,8 @@
         const bool workListsDirty = mHwWorkListDirty;
         mHwWorkListDirty = false;
         for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-            const DisplayDevice& hw(mDisplays[dpy]);
-            const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
+            sp<const DisplayDevice> hw(mDisplays[dpy]);
+            const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
             const size_t count = currentLayers.size();
 
             hwc.createWorkList(count); // FIXME: the worklist should include enough space for all layer of all displays
@@ -653,27 +652,27 @@
 
     const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
     for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-        DisplayDevice& hw(mDisplays.editValueAt(dpy));
+        const sp<DisplayDevice>& hw(mDisplays[dpy]);
 
         // transform the dirty region into this screen's coordinate space
-        const Transform& planeTransform(hw.getTransform());
+        const Transform& planeTransform(hw->getTransform());
         Region dirtyRegion;
         if (repaintEverything) {
-            dirtyRegion.set(hw.bounds());
+            dirtyRegion.set(hw->bounds());
         } else {
-            dirtyRegion = planeTransform.transform(hw.dirtyRegion);
-            dirtyRegion.andSelf(hw.bounds());
+            dirtyRegion = planeTransform.transform(hw->dirtyRegion);
+            dirtyRegion.andSelf(hw->bounds());
         }
-        hw.dirtyRegion.clear();
+        hw->dirtyRegion.clear();
 
         if (!dirtyRegion.isEmpty()) {
-            if (hw.canDraw()) {
+            if (hw->canDraw()) {
                 // repaint the framebuffer (if needed)
                 handleRepaint(hw, dirtyRegion);
             }
         }
         // inform the h/w that we're done compositing
-        hw.compositionComplete();
+        hw->compositionComplete();
     }
 
     postFramebuffer();
@@ -699,8 +698,8 @@
             glMatrixMode(GL_MODELVIEW);
             glLoadIdentity();
 
-            DisplayDevice& hw(const_cast<DisplayDevice&>(getDefaultDisplayDevice()));
-            const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() );
+            const sp<DisplayDevice>& hw(getDisplayDevice(0));
+            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]);
@@ -710,7 +709,7 @@
             success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
             ALOGE_IF(!success, "external display eglSwapBuffers failed");
 
-            hw.compositionComplete();
+            hw->compositionComplete();
         }
 
         success = eglMakeCurrent(eglGetCurrentDisplay(),
@@ -732,9 +731,9 @@
     HWComposer& hwc(getHwComposer());
 
     for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-        DisplayDevice& hw(mDisplays.editValueAt(dpy));
+        const sp<DisplayDevice>& hw(mDisplays[dpy]);
         if (hwc.initCheck() == NO_ERROR) {
-            const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
+            const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
             const size_t count = currentLayers.size();
             HWComposer::LayerListIterator cur = hwc.begin();
             const HWComposer::LayerListIterator end = hwc.end();
@@ -743,18 +742,18 @@
                 layer->setAcquireFence(hw, *cur);
             }
         }
-        hw.flip(hw.swapRegion);
-        hw.swapRegion.clear();
+        hw->flip(hw->swapRegion);
+        hw->swapRegion.clear();
     }
 
     if (hwc.initCheck() == NO_ERROR) {
         // FIXME: eventually commit() won't take arguments
-        hwc.commit(mEGLDisplay, getDefaultDisplayDevice().getEGLSurface());
+        hwc.commit(mEGLDisplay, getDefaultDisplayDevice()->getEGLSurface());
     }
 
     for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-        const DisplayDevice& hw(mDisplays[dpy]);
-        const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
+        sp<const DisplayDevice> hw(mDisplays[dpy]);
+        const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
         const size_t count = currentLayers.size();
         if (hwc.initCheck() == NO_ERROR) {
             HWComposer::LayerListIterator cur = hwc.begin();
@@ -763,7 +762,7 @@
                 currentLayers[i]->onLayerDisplayed(hw, &*cur);
             }
         } else {
-            eglSwapBuffers(mEGLDisplay, hw.getEGLSurface());
+            eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
             for (size_t i = 0; i < count; i++) {
                 currentLayers[i]->onLayerDisplayed(hw, NULL);
             }
@@ -846,7 +845,6 @@
                 if (curr.indexOfKey(draw[i].id) < 0) {
                     // in drawing state but not in current state
                     if (draw[i].id != DisplayDevice::DISPLAY_ID_MAIN) {
-                        mDisplays.editValueFor(draw[i].id).terminate();
                         mDisplays.removeItem(draw[i].id);
                     } else {
                         ALOGW("trying to remove the main display");
@@ -855,12 +853,12 @@
                     // this display is in both lists. see if something changed.
                     const DisplayDeviceState& state(curr[i]);
                     if (state.layerStack != draw[i].layerStack) {
-                        DisplayDevice& disp(mDisplays.editValueFor(state.id));
-                        //disp.setLayerStack(state.layerStack);
+                        const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
+                        //disp->setLayerStack(state.layerStack); // FIXME: set layer stack
                     }
                     if (curr[i].orientation != draw[i].orientation) {
-                        DisplayDevice& disp(mDisplays.editValueFor(state.id));
-                        disp.setOrientation(state.orientation);
+                        const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
+                        disp->setOrientation(state.orientation);
                     }
                 }
             }
@@ -870,7 +868,7 @@
             for (size_t i=0 ; i<cc ; i++) {
                 if (mDrawingState.displays.indexOfKey(curr[i].id) < 0) {
                     // FIXME: we need to pass the surface here
-                    DisplayDevice disp(this, curr[i].id, 0, mEGLConfig);
+                    sp<DisplayDevice> disp = new DisplayDevice(this, curr[i].id, 0, mEGLConfig);
                     mDisplays.add(curr[i].id, disp);
                 }
             }
@@ -1054,9 +1052,9 @@
 void SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
         const Region& dirty) {
     for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-        DisplayDevice& hw(mDisplays.editValueAt(dpy));
-        if (hw.getLayerStack() == layerStack) {
-            hw.dirtyRegion.orSelf(dirty);
+        const sp<DisplayDevice>& hw(mDisplays[dpy]);
+        if (hw->getLayerStack() == layerStack) {
+            hw->dirtyRegion.orSelf(dirty);
         }
     }
 }
@@ -1102,7 +1100,7 @@
     }
 }
 
-void SurfaceFlinger::handleRepaint(const DisplayDevice& hw,
+void SurfaceFlinger::handleRepaint(const sp<const DisplayDevice>& hw,
         const Region& inDirtyRegion)
 {
     ATRACE_CALL();
@@ -1110,29 +1108,29 @@
     Region dirtyRegion(inDirtyRegion);
 
     // compute the invalid region
-    hw.swapRegion.orSelf(dirtyRegion);
+    hw->swapRegion.orSelf(dirtyRegion);
 
     if (CC_UNLIKELY(mDebugRegion)) {
         debugFlashRegions(hw, dirtyRegion);
     }
 
-    uint32_t flags = hw.getFlags();
+    uint32_t flags = hw->getFlags();
     if (flags & DisplayDevice::SWAP_RECTANGLE) {
         // we can redraw only what's dirty, but since SWAP_RECTANGLE only
         // takes a rectangle, we must make sure to update that whole
         // rectangle in that case
-        dirtyRegion.set(hw.swapRegion.bounds());
+        dirtyRegion.set(hw->swapRegion.bounds());
     } else {
         if (flags & DisplayDevice::PARTIAL_UPDATES) {
             // We need to redraw the rectangle that will be updated
             // (pushed to the framebuffer).
             // This is needed because PARTIAL_UPDATES only takes one
             // rectangle instead of a region (see DisplayDevice::flip())
-            dirtyRegion.set(hw.swapRegion.bounds());
+            dirtyRegion.set(hw->swapRegion.bounds());
         } else {
             // we need to redraw everything (the whole screen)
-            dirtyRegion.set(hw.bounds());
-            hw.swapRegion = dirtyRegion;
+            dirtyRegion.set(hw->bounds());
+            hw->swapRegion = dirtyRegion;
         }
     }
 
@@ -1145,10 +1143,10 @@
     }
 
     // update the swap region and clear the dirty region
-    hw.swapRegion.orSelf(dirtyRegion);
+    hw->swapRegion.orSelf(dirtyRegion);
 }
 
-void SurfaceFlinger::composeSurfaces(const DisplayDevice& hw, const Region& dirty)
+void SurfaceFlinger::composeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
 {
     HWComposer& hwc(getHwComposer());
     HWComposer::LayerListIterator cur = hwc.begin();
@@ -1173,7 +1171,7 @@
             glClearColor(0, 0, 0, 0);
             glClear(GL_COLOR_BUFFER_BIT);
         } else {
-            const Region region(hw.undefinedRegion.intersect(dirty));
+            const Region region(hw->undefinedRegion.intersect(dirty));
             // screen is already cleared here
             if (!region.isEmpty()) {
                 // can happen with SurfaceView
@@ -1185,9 +1183,9 @@
          * and then, render the layers targeted at the framebuffer
          */
 
-        const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
+        const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
         const size_t count = layers.size();
-        const Transform& tr = hw.getTransform();
+        const Transform& tr = hw->getTransform();
         for (size_t i=0 ; i<count ; ++i) {
             const sp<LayerBase>& layer(layers[i]);
             const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
@@ -1212,18 +1210,18 @@
     }
 }
 
-void SurfaceFlinger::debugFlashRegions(const DisplayDevice& hw,
+void SurfaceFlinger::debugFlashRegions(const sp<const DisplayDevice>& hw,
         const Region& dirtyRegion)
 {
-    const uint32_t flags = hw.getFlags();
-    const int32_t height = hw.getHeight();
-    if (hw.swapRegion.isEmpty()) {
+    const uint32_t flags = hw->getFlags();
+    const int32_t height = hw->getHeight();
+    if (hw->swapRegion.isEmpty()) {
         return;
     }
 
     if (!(flags & DisplayDevice::SWAP_RECTANGLE)) {
         const Region repaint((flags & DisplayDevice::PARTIAL_UPDATES) ?
-                dirtyRegion.bounds() : hw.bounds());
+                dirtyRegion.bounds() : hw->bounds());
         composeSurfaces(hw, repaint);
     }
 
@@ -1253,7 +1251,7 @@
         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
-    hw.flip(hw.swapRegion);
+    hw->flip(hw->swapRegion);
 
     if (mDebugRegion > 1)
         usleep(mDebugRegion * 1000);
@@ -1618,18 +1616,18 @@
 
 void SurfaceFlinger::onScreenAcquired() {
     ALOGD("Screen about to return, flinger = %p", this);
-    const DisplayDevice& hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
+    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
     getHwComposer().acquire();
-    hw.acquireScreen();
+    hw->acquireScreen();
     mEventThread->onScreenAcquired();
 }
 
 void SurfaceFlinger::onScreenReleased() {
     ALOGD("About to give-up screen, flinger = %p", this);
-    const DisplayDevice& hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
-    if (hw.isScreenAcquired()) {
+    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
+    if (hw->isScreenAcquired()) {
         mEventThread->onScreenReleased();
-        hw.releaseScreen();
+        hw->releaseScreen();
         getHwComposer().release();
         // from this point on, SF will stop drawing
     }
@@ -1827,7 +1825,7 @@
     result.append(buffer);
 
     HWComposer& hwc(getHwComposer());
-    const DisplayDevice& hw(getDefaultDisplayDevice());
+    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
     const GLExtensions& extensions(GLExtensions::getInstance());
     snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
             extensions.getVendor(),
@@ -1842,10 +1840,10 @@
     snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
     result.append(buffer);
 
-    hw.undefinedRegion.dump(result, "undefinedRegion");
+    hw->undefinedRegion.dump(result, "undefinedRegion");
     snprintf(buffer, SIZE,
             "  orientation=%d, canDraw=%d\n",
-            hw.getOrientation(), hw.canDraw());
+            hw->getOrientation(), hw->canDraw());
     result.append(buffer);
     snprintf(buffer, SIZE,
             "  last eglSwapBuffers() time: %f us\n"
@@ -1859,9 +1857,9 @@
             mLastTransactionTime/1000.0,
             mTransactionFlags,
             1e9 / hwc.getRefreshPeriod(),
-            hw.getDpiX(),
-            hw.getDpiY(),
-            hw.getDensity());
+            hw->getDpiX(),
+            hw->getDpiY(),
+            hw->getDensity());
     result.append(buffer);
 
     snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
@@ -1886,14 +1884,14 @@
             hwc.initCheck()==NO_ERROR ? "present" : "not present",
                     (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
     result.append(buffer);
-    hwc.dump(result, buffer, SIZE, hw.getVisibleLayersSortedByZ());
+    hwc.dump(result, buffer, SIZE, hw->getVisibleLayersSortedByZ());
 
     /*
      * Dump gralloc state
      */
     const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
     alloc.dump(result);
-    hw.dump(result);
+    hw->dump(result);
 }
 
 status_t SurfaceFlinger::onTransact(
@@ -1990,8 +1988,8 @@
                 return NO_ERROR;
             case 1013: {
                 Mutex::Autolock _l(mStateLock);
-                const DisplayDevice& hw(getDefaultDisplayDevice());
-                reply->writeInt32(hw.getPageFlipCount());
+                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+                reply->writeInt32(hw->getPageFlipCount());
             }
             return NO_ERROR;
         }
@@ -2022,9 +2020,9 @@
         return INVALID_OPERATION;
 
     // get screen geometry
-    const DisplayDevice& hw(getDisplayDevice(dpy));
-    const uint32_t hw_w = hw.getWidth();
-    const uint32_t hw_h = hw.getHeight();
+    sp<const DisplayDevice> hw(getDisplayDevice(dpy));
+    const uint32_t hw_w = hw->getWidth();
+    const uint32_t hw_h = hw->getHeight();
     GLfloat u = 1;
     GLfloat v = 1;
 
@@ -2060,14 +2058,14 @@
     glClear(GL_COLOR_BUFFER_BIT);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
-    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
+    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]);
         layer->draw(hw);
     }
 
-    hw.compositionComplete();
+    hw->compositionComplete();
 
     // back to main framebuffer
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
@@ -2101,12 +2099,12 @@
     }
 
     // get screen geometry
-    const DisplayDevice& hw(getDisplayDevice(dpy));
-    const uint32_t hw_w = hw.getWidth();
-    const uint32_t hw_h = hw.getHeight();
+    sp<const DisplayDevice> hw(getDisplayDevice(dpy));
+    const uint32_t hw_w = hw->getWidth();
+    const uint32_t hw_h = hw->getHeight();
 
     // if we have secure windows on this display, never allow the screen capture
-    if (hw.getSecureLayerVisible()) {
+    if (hw->getSecureLayerVisible()) {
         return PERMISSION_DENIED;
     }
 
@@ -2205,7 +2203,7 @@
     glDeleteRenderbuffersOES(1, &tname);
     glDeleteFramebuffersOES(1, &name);
 
-    hw.compositionComplete();
+    hw->compositionComplete();
 
     // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index feeccf6..da417ff 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -118,7 +118,7 @@
         GLfloat* uOut, GLfloat* vOut);
 
     // returns the default Display
-    const DisplayDevice& getDefaultDisplayDevice() const {
+    sp<const DisplayDevice> getDefaultDisplayDevice() const {
         return getDisplayDevice(DisplayDevice::DISPLAY_ID_MAIN);
     }
 
@@ -245,7 +245,7 @@
     void handlePageFlip();
 
     void handleRefresh();
-    void handleRepaint(const DisplayDevice& hw, const Region& dirtyRegion);
+    void handleRepaint(const sp<const DisplayDevice>& hw, const Region& dirtyRegion);
 
     /* ------------------------------------------------------------------------
      * Transactions
@@ -319,11 +319,11 @@
     /* ------------------------------------------------------------------------
      * Display and layer stack management
      */
-    const DisplayDevice& getDisplayDevice(DisplayID dpy) const {
+    sp<const DisplayDevice> getDisplayDevice(DisplayID dpy) const {
         return mDisplays.valueFor(dpy);
     }
-    DisplayDevice& getDisplayDevice(DisplayID dpy) {
-        return mDisplays.editValueFor(dpy);
+    const sp<DisplayDevice>& getDisplayDevice(DisplayID dpy) {
+        return mDisplays.valueFor(dpy);
     }
 
     // mark a region of a layer stack dirty. this updates the dirty
@@ -344,7 +344,7 @@
             uint32_t layerStack,
             Region& dirtyRegion, Region& opaqueRegion);
     void postFramebuffer();
-    void composeSurfaces(const DisplayDevice& hw, const Region& dirty);
+    void composeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty);
     void drawWormhole(const Region& region) const;
     GLuint getProtectedTexName() const {
         return mProtectedTexName;
@@ -353,7 +353,7 @@
     /* ------------------------------------------------------------------------
      * Debugging & dumpsys
      */
-    void debugFlashRegions(const DisplayDevice& hw, const Region& dirtyReg);
+    void debugFlashRegions(const sp<const DisplayDevice>& hw, const Region& dirtyReg);
     void listLayersLocked(const Vector<String16>& args, size_t& index,
         String8& result, char* buffer, size_t SIZE) const;
     void dumpStatsLocked(const Vector<String16>& args, size_t& index,
@@ -397,7 +397,7 @@
     State mDrawingState;
     bool mVisibleRegionsDirty;
     bool mHwWorkListDirty;
-    DefaultKeyedVector<int32_t, DisplayDevice> mDisplays;
+    DefaultKeyedVector<int32_t, sp<DisplayDevice> > mDisplays;
 
     // don't use a lock for these, we don't care
     int mDebugRegion;