From f5a33928349bebc8eebc9f466618997e98c24e68 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 19 Sep 2012 18:16:22 -0700 Subject: [PATCH] we now correctly set-up connected screens during boot Change-Id: Ie8b1a3b97ad1821cc970e43abe96c8cec7135b66 --- .../DisplayHardware/FramebufferSurface.cpp | 13 ++--- .../DisplayHardware/FramebufferSurface.h | 5 +- .../DisplayHardware/HWComposer.cpp | 19 ++++--- .../DisplayHardware/HWComposer.h | 4 +- services/surfaceflinger/SurfaceFlinger.cpp | 53 ++++++++++--------- 5 files changed, 53 insertions(+), 41 deletions(-) diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp index 8c6ecc03a..9ada19712 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp @@ -46,8 +46,9 @@ namespace android { * */ -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 @@ FramebufferSurface::FramebufferSurface(HWComposer& hwc) : 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 @@ void FramebufferSurface::onFrameAvailable() { 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 717a3f16f..d64fea78b 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h @@ -36,7 +36,7 @@ class HWComposer; 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 @@ private: // BufferQueue. The new buffer is returned in the 'buffer' argument. status_t nextBuffer(sp& outBuffer, sp& 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 09ac78d10..6509a1246 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -301,10 +301,7 @@ void HWComposer::hotplug(int disp, int connected) { disp, connected); return; } - - if (connected) - queryDisplayProperties(disp); - + queryDisplayProperties(disp); mEventHandler.onHotplugReceived(disp, bool(connected)); } @@ -335,6 +332,7 @@ status_t HWComposer::queryDisplayProperties(int disp) { 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 @@ status_t HWComposer::queryDisplayProperties(int disp) { } } + // 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 @@ float HWComposer::getDpiY(int disp) const { 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 @@ status_t HWComposer::setFramebufferTarget(int32_t id, // 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 ff39bc143..8f6665165 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -234,6 +234,7 @@ public: 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 @@ private: 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 @@ private: 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 427e46f99..0ce526637 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -405,34 +405,35 @@ status_t SurfaceFlinger::readyToRun() // initialize our non-virtual displays for (size_t i=0 ; i token = mDefaultDisplays[i]; + mCurrentState.displays.add(token, DisplayDeviceState(type)); + + // set-up the displays that are already connected + if (mHwc->isConnected(i)) { + sp fbs = new FramebufferSurface(*mHwc, i); + sp stc = new SurfaceTextureClient( + static_cast< sp >(fbs->getBufferQueue())); + sp 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 fbs = new FramebufferSurface(*mHwc); - sp stc = new SurfaceTextureClient( - static_cast< sp >(fbs->getBufferQueue())); - sp 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 hw = getDefaultDisplayDevice(); // initialize OpenGL ES DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext); @@ -1076,7 +1077,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) // 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 >(fbs->getBufferQueue())); } else {