we now correctly set-up connected screens during boot

Change-Id: Ie8b1a3b97ad1821cc970e43abe96c8cec7135b66
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 8c6ecc0..9ada197 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -46,8 +46,9 @@
  *
  */
 
-FramebufferSurface::FramebufferSurface(HWComposer& hwc) :
+FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp) :
     ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())),
+    mDisplayType(disp),
     mCurrentBufferSlot(-1),
     mCurrentBuffer(0),
     mHwc(hwc)
@@ -55,10 +56,10 @@
     mName = "FramebufferSurface";
     mBufferQueue->setConsumerName(mName);
     mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
-                                       GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER);
-    mBufferQueue->setDefaultBufferFormat(mHwc.getFormat(HWC_DISPLAY_PRIMARY));
-    mBufferQueue->setDefaultBufferSize(mHwc.getWidth(HWC_DISPLAY_PRIMARY),
-                                       mHwc.getHeight(HWC_DISPLAY_PRIMARY));
+                                       GRALLOC_USAGE_HW_RENDER |
+                                       GRALLOC_USAGE_HW_COMPOSER);
+    mBufferQueue->setDefaultBufferFormat(mHwc.getFormat(disp));
+    mBufferQueue->setDefaultBufferSize(mHwc.getWidth(disp),  mHwc.getHeight(disp));
     mBufferQueue->setSynchronousMode(true);
     mBufferQueue->setDefaultMaxBufferCount(NUM_FRAME_BUFFERS);
 }
@@ -111,7 +112,7 @@
                 strerror(-err), err);
         return;
     }
-    err = mHwc.fbPost(0, acquireFence, buf); // FIXME: use real display id
+    err = mHwc.fbPost(mDisplayType, acquireFence, buf);
     if (err != NO_ERROR) {
         ALOGE("error posting framebuffer: %d", err);
     }
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 717a3f1..d64fea7 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -36,7 +36,7 @@
 
 class FramebufferSurface : public ConsumerBase {
 public:
-    FramebufferSurface(HWComposer& hwc);
+    FramebufferSurface(HWComposer& hwc, int disp);
 
     bool isUpdateOnDemand() const { return false; }
     status_t setUpdateRectangle(const Rect& updateRect);
@@ -63,6 +63,9 @@
     // BufferQueue.  The new buffer is returned in the 'buffer' argument.
     status_t nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence);
 
+    // mDisplayType must match one of the HWC display types
+    int mDisplayType;
+
     // mCurrentBufferIndex is the slot index of the current buffer or
     // INVALID_BUFFER_SLOT to indicate that either there is no current buffer
     // or the buffer is not associated with a slot.
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 09ac78d..6509a12 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -301,10 +301,7 @@
                 disp, connected);
         return;
     }
-
-    if (connected)
-        queryDisplayProperties(disp);
-
+    queryDisplayProperties(disp);
     mEventHandler.onHotplugReceived(disp, bool(connected));
 }
 
@@ -335,6 +332,7 @@
     status_t err = mHwc->getDisplayConfigs(mHwc, disp, &config, &numConfigs);
     if (err != NO_ERROR) {
         // this can happen if an unpluggable display is not connected
+        mDisplayData[disp].connected = false;
         return err;
     }
 
@@ -365,6 +363,9 @@
         }
     }
 
+    // FIXME: what should we set the format to?
+    mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888;
+    mDisplayData[disp].connected = true;
     if (mDisplayData[disp].xdpi == 0.0f || mDisplayData[disp].ydpi == 0.0f) {
         // is there anything smarter we can do?
         if (h >= 1080) {
@@ -432,6 +433,10 @@
     return mDisplayData[disp].ydpi;
 }
 
+bool HWComposer::isConnected(int disp) const {
+    return mDisplayData[disp].connected;
+}
+
 void HWComposer::eventControl(int event, int enabled) {
     status_t err = NO_ERROR;
     if (mHwc) {
@@ -503,9 +508,9 @@
         // triggers a SurfaceTextureClient::queueBuffer()  on some
         // devices (!?) -- log and ignore.
         ALOGE("HWComposer: framebufferTarget is null");
-        CallStack stack;
-        stack.update();
-        stack.dump("");
+//        CallStack stack;
+//        stack.update();
+//        stack.dump("");
         return NO_ERROR;
     }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index ff39bc1..8f66651 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -234,6 +234,7 @@
     uint32_t getFormat(int disp) const;
     float getDpiX(int disp) const;
     float getDpiY(int disp) const;
+    bool isConnected(int disp) const;
 
     // this class is only used to fake the VSync event on systems that don't
     // have it.
@@ -283,7 +284,7 @@
 
     struct DisplayData {
         DisplayData() : xdpi(0), ydpi(0), refresh(0),
-            hasFbComp(false), hasOvComp(false),
+            connected(false), hasFbComp(false), hasOvComp(false),
             capacity(0), list(NULL),
             framebufferTarget(NULL), fbTargetHandle(NULL) { }
         ~DisplayData() {
@@ -295,6 +296,7 @@
         float xdpi;
         float ydpi;
         nsecs_t refresh;
+        bool connected;
         bool hasFbComp;
         bool hasOvComp;
         size_t capacity;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 427e46f..0ce5266 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -405,34 +405,35 @@
 
     // initialize our non-virtual displays
     for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
+        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
         mDefaultDisplays[i] = new BBinder();
-        mCurrentState.displays.add(mDefaultDisplays[i],
-                DisplayDeviceState(DisplayDevice::DisplayType(i)));
+        wp<IBinder> token = mDefaultDisplays[i];
+        mCurrentState.displays.add(token, DisplayDeviceState(type));
+
+        // set-up the displays that are already connected
+        if (mHwc->isConnected(i)) {
+            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i);
+            sp<SurfaceTextureClient> stc = new SurfaceTextureClient(
+                        static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
+            sp<DisplayDevice> hw = new DisplayDevice(this,
+                    type, token, stc, fbs, mEGLConfig);
+
+            if (i > DisplayDevice::DISPLAY_PRIMARY) {
+                // FIXME: currently we don't really handle blank/unblank
+                // for displays other than the main display, so we always
+                // assume a connected display is unblanked.
+                hw->acquireScreen();
+            }
+            mDisplays.add(token, hw);
+        }
     }
 
-    // The main display is a bit special and always exists
-    //
-    // if we didn't add it here, it would be added automatically during the
-    // first transaction, however this would also create some difficulties:
-    //
-    // - there would be a race where a client could call getDisplayInfo(),
-    //   for instance before the DisplayDevice is created.
-    //
-    // - we need a GL context current in a few places, when initializing
-    //   OpenGL ES (see below), or creating a layer,
-    //   or when a texture is (asynchronously) destroyed, and for that
-    //   we need a valid surface, so it's conveniant to use the main display
-    //   for that.
-
-    sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc);
-    sp<SurfaceTextureClient> stc = new SurfaceTextureClient(
-                static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
-    sp<DisplayDevice> hw = new DisplayDevice(this,
-            DisplayDevice::DISPLAY_PRIMARY,
-            mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY],
-            stc, fbs, mEGLConfig);
-    mDisplays.add(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], hw);
-
+    //  we need a GL context current in a few places, when initializing
+    //  OpenGL ES (see below), or creating a layer,
+    //  or when a texture is (asynchronously) destroyed, and for that
+    //  we need a valid surface, so it's convenient to use the main display
+    //  for that.
+    sp<const DisplayDevice> hw = getDefaultDisplayDevice();
 
     //  initialize OpenGL ES
     DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
@@ -1076,7 +1077,7 @@
 
                         // for supported (by hwc) displays we provide our
                         // own rendering surface
-                        fbs = new FramebufferSurface(*mHwc);
+                        fbs = new FramebufferSurface(*mHwc, state.type);
                         stc = new SurfaceTextureClient(
                                 static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
                     } else {