auto import from //branches/cupcake/...@126645
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 19e32ec..92588fa 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -23,6 +23,8 @@
 
 #include <GLES/egl.h>
 
+#include <cutils/properties.h>
+
 #include <utils/Log.h>
 
 #include <ui/EGLDisplaySurface.h>
@@ -193,11 +195,14 @@
     }
     mRefreshRate = 60.f;    // TODO: get the real refresh rate 
     
-    // compute a "density" automatically as a scale factor from 160 dpi
-    // TODO: this value should be calculated a compile time based on the
-    // board.
-    mDensity = floorf((mDpiX>mDpiY ? mDpiX : mDpiY)*0.1f + 0.5f) * (10.0f/160.0f);
-    LOGI("density = %f", mDensity);
+    
+    char property[PROPERTY_VALUE_MAX];
+    if (property_get("ro.sf.lcd_density", property, NULL) <= 0) {
+        LOGW("ro.sf.lcd_density not defined, using 160 dpi by default.");
+        strcpy(property, "160");
+    }
+    mDensity = atoi(property) * (1.0f/160.0f);
+
 
     /*
      * Create our OpenGL ES context
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 700e4f5..c9cebf4 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -95,10 +95,9 @@
 
 void LayerBuffer::unregisterBuffers()
 {
-    sp<Source> source(getSource());
+    sp<Source> source(clearSource());
     if (source != 0)
         source->unregisterBuffers();
-    // XXX: clear mSource
 }
 
 uint32_t LayerBuffer::doTransaction(uint32_t flags)
@@ -172,6 +171,14 @@
     return mSource;
 }
 
+sp<LayerBuffer::Source> LayerBuffer::clearSource() {
+    sp<Source> source;
+    Mutex::Autolock _l(mLock);
+    source = mSource;
+    mSource.clear();
+    return source;
+}
+
 // ============================================================================
 // LayerBuffer::SurfaceBuffer
 // ============================================================================
@@ -477,15 +484,16 @@
 LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer,
         sp<OverlayRef>* overlayRef, 
         uint32_t w, uint32_t h, int32_t format)
-    : Source(layer), mVisibilityChanged(false), mOverlay(0), mOverlayHandle(0)
+    : Source(layer), mVisibilityChanged(false),
+    mOverlay(0), mOverlayHandle(0), mOverlayDevice(0)
 {
     overlay_control_device_t* overlay_dev = mLayer.mFlinger->getOverlayEngine();
-
     if (overlay_dev == NULL) {
         // overlays not supported
         return;
     }
 
+    mOverlayDevice = overlay_dev;
     overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format);
     if (overlay == NULL) {
         // couldn't create the overlay (no memory? no more overlays?)
@@ -507,14 +515,18 @@
     
     // NOTE: here it's okay to acquire a reference to "this"m as long as
     // the reference is not released before we leave the ctor.
-    sp<OverlayChanel> chanel = new OverlayChanel(this);
+    sp<OverlayChannel> channel = new OverlayChannel(this);
 
-    *overlayRef = new OverlayRef(mOverlayHandle, chanel,
+    *overlayRef = new OverlayRef(mOverlayHandle, channel,
             mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
 }
 
 LayerBuffer::OverlaySource::~OverlaySource()
-{    
+{
+    if (mOverlay && mOverlayDevice) {
+        overlay_control_device_t* overlay_dev = mOverlayDevice;
+        overlay_dev->destroyOverlay(overlay_dev, mOverlay);
+    }
 }
 
 void LayerBuffer::OverlaySource::onTransaction(uint32_t flags)
@@ -543,8 +555,7 @@
             // we need a lock here to protect "destroy"
             Mutex::Autolock _l(mLock);
             if (mOverlay) {
-                overlay_control_device_t* overlay_dev = 
-                    mLayer.mFlinger->getOverlayEngine();
+                overlay_control_device_t* overlay_dev = mOverlayDevice;
                 overlay_dev->setPosition(overlay_dev, mOverlay, x,y,w,h);
                 overlay_dev->setParameter(overlay_dev, mOverlay, 
                         OVERLAY_TRANSFORM, mLayer.getOrientation());
@@ -555,11 +566,16 @@
 
 void LayerBuffer::OverlaySource::serverDestroy() 
 {
+    mLayer.clearSource();
+    destroyOverlay();
+}
+
+void LayerBuffer::OverlaySource::destroyOverlay() 
+{
     // we need a lock here to protect "onVisibilityResolved"
     Mutex::Autolock _l(mLock);
     if (mOverlay) {
-        overlay_control_device_t* overlay_dev = 
-                mLayer.mFlinger->getOverlayEngine();
+        overlay_control_device_t* overlay_dev = mOverlayDevice;
         overlay_dev->destroyOverlay(overlay_dev, mOverlay);
         mOverlay = 0;
     }
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 63ec2cf..3286535 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -75,6 +75,7 @@
     sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format);
     
     sp<Source> getSource() const;
+    sp<Source> clearSource();
     void setNeedsBlending(bool blending);
     const Rect& getTransformedBounds() const {
         return mTransformedBounds;
@@ -145,7 +146,8 @@
         virtual void onVisibilityResolved(const Transform& planeTransform);
     private:
         void serverDestroy(); 
-        class OverlayChanel : public BnOverlay {
+        void destroyOverlay(); 
+        class OverlayChannel : public BnOverlay {
             mutable Mutex mLock;
             sp<OverlaySource> mSource;
             virtual void destroy() {
@@ -160,15 +162,16 @@
                 }
             }
         public:
-            OverlayChanel(const sp<OverlaySource>& source)
+            OverlayChannel(const sp<OverlaySource>& source)
                 : mSource(source) {
             }
         };
-        friend class OverlayChanel;
+        friend class OverlayChannel;
         bool mVisibilityChanged;
 
         overlay_t* mOverlay;        
         overlay_handle_t const *mOverlayHandle;
+        overlay_control_device_t* mOverlayDevice;
         uint32_t mWidth;
         uint32_t mHeight;
         int32_t mFormat;
diff --git a/libs/surfaceflinger/tests/Android.mk b/libs/surfaceflinger/tests/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/libs/surfaceflinger/tests/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/libs/surfaceflinger/tests/overlays/Android.mk b/libs/surfaceflinger/tests/overlays/Android.mk
new file mode 100644
index 0000000..dc47e45
--- /dev/null
+++ b/libs/surfaceflinger/tests/overlays/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	overlays.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+    libui
+
+LOCAL_MODULE:= test-overlays
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/libs/surfaceflinger/tests/overlays/overlays.cpp b/libs/surfaceflinger/tests/overlays/overlays.cpp
new file mode 100644
index 0000000..f3c046f
--- /dev/null
+++ b/libs/surfaceflinger/tests/overlays/overlays.cpp
@@ -0,0 +1,58 @@
+#include <utils/IPCThreadState.h>
+#include <utils/ProcessState.h>
+#include <utils/IServiceManager.h>
+#include <utils/Log.h>
+
+#include <ui/Surface.h>
+#include <ui/ISurface.h>
+#include <ui/Overlay.h>
+#include <ui/SurfaceComposerClient.h>
+
+using namespace android;
+
+namespace android {
+class Test {
+public:
+    static const sp<ISurface>& getISurface(const sp<Surface>& s) {
+        return s->getISurface();
+    }
+};
+};
+
+int main(int argc, char** argv)
+{
+    // set up the thread-pool
+    sp<ProcessState> proc(ProcessState::self());
+    ProcessState::self()->startThreadPool();
+
+    // create a client to surfaceflinger
+    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
+    
+    // create pushbuffer surface
+    sp<Surface> surface = client->createSurface(getpid(), 0, 320, 240, 
+            PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers);
+
+    // get to the isurface
+    sp<ISurface> isurface = Test::getISurface(surface);
+    printf("isurface = %p\n", isurface.get());
+    
+    // now request an overlay
+    sp<OverlayRef> ref = isurface->createOverlay(320, 240, PIXEL_FORMAT_RGB_565);
+    sp<Overlay> overlay = new Overlay(ref);
+    
+
+    /*
+     * here we can use the overlay API 
+     */
+    
+    overlay_buffer_t buffer; 
+    overlay->dequeueBuffer(&buffer);
+    printf("buffer = %p\n", buffer);
+    
+    void* address = overlay->getBufferAddress(buffer);
+    printf("address = %p\n", address);
+
+    overlay->queueBuffer(buffer);
+
+    return 0;
+}