From 692c723e84e6f2747447d871d468ff50e5c73f19 Mon Sep 17 00:00:00 2001 From: Jesse Hall Date: Thu, 8 Nov 2012 15:41:56 -0800 Subject: [PATCH] Create builtin display tokens on demand For hotpluggable builtin displays (currently just HDMI), create the display device IBinder token when the display is connected and destroy it when the display is disconnected. Previously we created the tokens at startup and never changed them. This made it so that when comparing current and drawing state, we couldn't tell whether a display had been disconnected and reconnected. Bug: 7491120 Change-Id: I23b77037dc0f548d549abf580339edd0e3c626e9 --- services/surfaceflinger/SurfaceFlinger.cpp | 47 +++++++++++----------- services/surfaceflinger/SurfaceFlinger.h | 7 +++- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index ceb841175..614c529f7 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -191,12 +191,22 @@ sp SurfaceFlinger::createDisplay(const String8& displayName, return token; } +void SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { + ALOGW_IF(mBuiltinDisplays[type], + "Overwriting display token for display type %d", type); + mBuiltinDisplays[type] = new BBinder(); + DisplayDeviceState info(type); + // All non-virtual displays are currently considered secure. + info.isSecure = true; + mCurrentState.displays.add(mBuiltinDisplays[type], info); +} + sp SurfaceFlinger::getBuiltInDisplay(int32_t id) { if (uint32_t(id) >= DisplayDevice::NUM_DISPLAY_TYPES) { ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); return NULL; } - return mDefaultDisplays[id]; + return mBuiltinDisplays[id]; } sp SurfaceFlinger::createGraphicBufferAlloc() @@ -462,6 +472,8 @@ status_t SurfaceFlinger::readyToRun() ALOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W..."); + Mutex::Autolock _l(mStateLock); + // initialize EGL for the default display mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(mEGLDisplay, NULL, NULL); @@ -482,14 +494,13 @@ status_t SurfaceFlinger::readyToRun() // initialize our non-virtual displays for (size_t i=0 ; i token = mDefaultDisplays[i]; - // set-up the displays that are already connected if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) { // All non-virtual displays are currently considered secure. bool isSecure = true; - mCurrentState.displays.add(token, DisplayDeviceState(type)); + createBuiltinDisplayLocked(type); + wp token = mBuiltinDisplays[i]; + sp fbs = new FramebufferSurface(*mHwc, i); sp stc = new SurfaceTextureClient( static_cast< sp >(fbs->getBufferQueue())); @@ -601,9 +612,9 @@ bool SurfaceFlinger::authenticateSurfaceTexture( } status_t SurfaceFlinger::getDisplayInfo(const sp& display, DisplayInfo* info) { - int32_t type = BAD_VALUE; + int32_t type = NAME_NOT_FOUND; for (int i=0 ; i& display, DisplayInfo* } const HWComposer& hwc(getHwComposer()); - if (!hwc.isConnected(type)) { - return NAME_NOT_FOUND; - } - float xdpi = hwc.getDpiX(type); float ydpi = hwc.getDpiY(type); @@ -745,11 +752,11 @@ void SurfaceFlinger::onHotplugReceived(int type, bool connected) { if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) { Mutex::Autolock _l(mStateLock); - if (connected == false) { - mCurrentState.displays.removeItem(mDefaultDisplays[type]); + if (connected) { + createBuiltinDisplayLocked((DisplayDevice::DisplayType)type); } else { - DisplayDeviceState info((DisplayDevice::DisplayType)type); - mCurrentState.displays.add(mDefaultDisplays[type], info); + mCurrentState.displays.removeItem(mBuiltinDisplays[type]); + mBuiltinDisplays[type].clear(); } setTransactionFlags(eDisplayTransactionNeeded); @@ -1163,7 +1170,6 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) for (size_t i=0 ; i fbs; sp stc; @@ -1174,10 +1180,6 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) "surface is provided (%p), ignoring it", state.surface.get()); - // All non-virtual displays are currently considered - // secure. - isSecure = true; - // for supported (by hwc) displays we provide our // own rendering surface fbs = new FramebufferSurface(*mHwc, state.type); @@ -1188,13 +1190,12 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) if (state.surface != NULL) { stc = new SurfaceTextureClient(state.surface); } - isSecure = state.isSecure; } const wp& display(curr.keyAt(i)); if (stc != NULL) { sp hw = new DisplayDevice(this, - state.type, isSecure, display, stc, fbs, + state.type, state.isSecure, display, stc, fbs, mEGLConfig); hw->setLayerStack(state.layerStack); hw->setProjection(state.orientation, @@ -2011,7 +2012,7 @@ void SurfaceFlinger::onInitializeDisplays() { Vector displays; DisplayState d; d.what = DisplayState::eDisplayProjectionChanged; - d.token = mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY]; + d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; d.orientation = DisplayState::eOrientationDefault; d.frame.makeInvalid(); d.viewport.makeInvalid(); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index b0d3bacf5..1b549e421 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -112,7 +112,7 @@ public: // returns the default Display sp getDefaultDisplayDevice() const { - return getDisplayDevice(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY]); + return getDisplayDevice(mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]); } // utility function to delete a texture on the main thread @@ -328,6 +328,9 @@ private: // called when starting, or restarting after system_server death void initializeDisplays(); + // Create an IBinder for a builtin display and add it to current state + void createBuiltinDisplayLocked(DisplayDevice::DisplayType type); + // NOTE: can only be called from the main thread or with mStateLock held sp getDisplayDevice(const wp& dpy) const { return mDisplays.valueFor(dpy); @@ -422,7 +425,7 @@ private: EGLContext mEGLContext; EGLConfig mEGLConfig; EGLDisplay mEGLDisplay; - sp mDefaultDisplays[DisplayDevice::NUM_DISPLAY_TYPES]; + sp mBuiltinDisplays[DisplayDevice::NUM_DISPLAY_TYPES]; // Can only accessed from the main thread, these members // don't need synchronization