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 {