From cde87a3b9d3f8dc15232d927b56ee9e5e520f58d Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 13 Sep 2012 14:09:01 -0700 Subject: [PATCH] refactor things a bit - decouple GL and main display initialization - ensure that each "supported" display has its own FramebufferSurface - onScreenAcquired/Released now takes a display Change-Id: If34a05f3dea40f6c79db77f4dde283a2580daac4 --- .../DisplayHardware/HWComposer.cpp | 36 +++-- .../DisplayHardware/HWComposer.h | 4 + services/surfaceflinger/SurfaceFlinger.cpp | 140 ++++++++++++------ services/surfaceflinger/SurfaceFlinger.h | 7 +- 4 files changed, 125 insertions(+), 62 deletions(-) diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 1b55792fc..81640afd5 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -561,22 +561,34 @@ size_t HWComposer::getNumLayers(int32_t id) const { mDisplayData[id].list->numHwLayers : 0; } -int HWComposer::fbPost(buffer_handle_t buffer) -{ - return mFbDev->post(mFbDev, buffer); -} - -int HWComposer::fbCompositionComplete() -{ - if (mFbDev->compositionComplete) { - return mFbDev->compositionComplete(mFbDev); +int HWComposer::getVisualID() const { + if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { + return HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; } else { - return INVALID_OPERATION; + return mFbDev->format; } } +int HWComposer::fbPost(buffer_handle_t buffer) { + if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { + return mFbDev->post(mFbDev, buffer); + } + return NO_ERROR; +} + +int HWComposer::fbCompositionComplete() { + if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { + if (mFbDev->compositionComplete) { + return mFbDev->compositionComplete(mFbDev); + } else { + return INVALID_OPERATION; + } + } + return NO_ERROR; +} + void HWComposer::fbDump(String8& result) { - if (mFbDev->common.version >= 1 && mFbDev->dump) { + if (mFbDev && mFbDev->common.version >= 1 && mFbDev->dump) { const size_t SIZE = 4096; char buffer[SIZE]; mFbDev->dump(mFbDev, buffer, SIZE); @@ -727,7 +739,7 @@ HWComposer::LayerListIterator HWComposer::end(int32_t id) { void HWComposer::dump(String8& result, char* buffer, size_t SIZE, const Vector< sp >& visibleLayersSortedByZ) const { if (mHwc) { - result.append("Hardware Composer state:\n"); + result.appendFormat("Hardware Composer state (version %8x):\n", hwcApiVersion(mHwc)); result.appendFormat(" mDebugForceFakeVSync=%d\n", mDebugForceFakeVSync); for (size_t i=0 ; i #include +#include #include #include #include @@ -243,6 +244,16 @@ status_t SurfaceFlinger::selectConfigForPixelFormat( eglGetConfigs(dpy, NULL, 0, &numConfigs); EGLConfig* const configs = new EGLConfig[numConfigs]; eglChooseConfig(dpy, attrs, configs, numConfigs, &n); + + if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { + // FIXME: temporary hack until HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED + // is supported by the implementation. we can only be in this case + // if we have HWC 1.1 + *outConfig = configs[0]; + delete [] configs; + return NO_ERROR; + } + for (int i=0 ; i& hw) { - EGLBoolean result = DisplayDevice::makeCurrent(display, hw, mEGLContext); - if (!result) { - ALOGE("Couldn't create a working GLES context. check logs. exiting..."); - exit(0); - } - +void SurfaceFlinger::initializeGL(EGLDisplay display) { GLExtensions& extensions(GLExtensions::getInstance()); extensions.initWithGLStrings( glGetString(GL_VENDOR), @@ -375,39 +385,45 @@ status_t SurfaceFlinger::readyToRun() mHwc = new HWComposer(this, *static_cast(this)); - // Initialize the main display - // create native window to main display - sp fbs = new FramebufferSurface(*mHwc); - if (fbs == NULL) { - ALOGE("Display subsystem failed to initialize. check logs. exiting..."); - exit(0); - } - - sp stc(new SurfaceTextureClient( - static_cast >(fbs->getBufferQueue()))); - // initialize the config and context - int format; - ANativeWindow* const anw = stc.get(); - anw->query(anw, NATIVE_WINDOW_FORMAT, &format); + EGLint format = mHwc->getVisualID(); mEGLConfig = selectEGLConfig(mEGLDisplay, format); mEGLContext = createGLContext(mEGLDisplay, mEGLConfig); - // initialize our main display hardware - + // initialize our non-virtual displays for (size_t i=0 ; i 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], - anw, fbs, mEGLConfig); + stc, fbs, mEGLConfig); mDisplays.add(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], hw); + // initialize OpenGL ES - initializeGL(mEGLDisplay, hw); + DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext); + initializeGL(mEGLDisplay); // start the EventThread mEventThread = new EventThread(this); @@ -416,6 +432,7 @@ status_t SurfaceFlinger::readyToRun() // initialize our drawing state mDrawingState = mCurrentState; + // We're now ready to accept clients... mReadyToRunBarrier.open(); @@ -1009,16 +1026,41 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) for (size_t i=0 ; i stc( - new SurfaceTextureClient(state.surface)); - const wp& display(curr.keyAt(i)); - sp disp = new DisplayDevice(this, - state.type, display, stc, 0, mEGLConfig); - disp->setLayerStack(state.layerStack); - disp->setProjection(state.orientation, + + sp fbs; + sp stc; + if (!state.isVirtualDisplay()) { + + ALOGE_IF(state.surface!=NULL, + "adding a supported display, but rendering " + "surface is provided (%p), ignoring it", + state.surface.get()); + + // for supported (by hwc) displays we provide our + // own rendering surface + fbs = new FramebufferSurface(*mHwc); + stc = new SurfaceTextureClient( + static_cast< sp >(fbs->getBufferQueue())); + } else { + if (state.surface != NULL) { + stc = new SurfaceTextureClient(state.surface); + } + } + + const wp& display(curr.keyAt(i)); + if (stc != NULL) { + sp hw = new DisplayDevice(this, + state.type, display, stc, fbs, mEGLConfig); + hw->setLayerStack(state.layerStack); + hw->setProjection(state.orientation, state.viewport, state.frame); - mDisplays.add(display, disp); + mDisplays.add(display, hw); + if (hw->getDisplayType() < DisplayDevice::NUM_DISPLAY_TYPES) { + // notify the system that this display is now up + // (note onScreenAcquired() is safe to call from + // here because we're in the main thread) + onScreenAcquired(hw); + } } } } @@ -1753,9 +1795,7 @@ void SurfaceFlinger::onInitializeDisplays() { d.viewport.makeInvalid(); displays.add(d); setTransactionState(state, displays, 0); - - // XXX: this should init default device to "unblank" and all other devices to "blank" - onScreenAcquired(); + onScreenAcquired(getDefaultDisplayDevice()); } void SurfaceFlinger::initializeDisplays() { @@ -1773,21 +1813,25 @@ void SurfaceFlinger::initializeDisplays() { } -void SurfaceFlinger::onScreenAcquired() { +void SurfaceFlinger::onScreenAcquired(const sp& hw) { ALOGD("Screen about to return, flinger = %p", this); - sp hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice getHwComposer().acquire(); hw->acquireScreen(); - mEventThread->onScreenAcquired(); + if (hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) { + // FIXME: eventthread only knows about the main display right now + mEventThread->onScreenAcquired(); + } mVisibleRegionsDirty = true; repaintEverything(); } -void SurfaceFlinger::onScreenReleased() { +void SurfaceFlinger::onScreenReleased(const sp& hw) { ALOGD("About to give-up screen, flinger = %p", this); - sp hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice if (hw->isScreenAcquired()) { - mEventThread->onScreenReleased(); + if (hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) { + // FIXME: eventthread only knows about the main display right now + mEventThread->onScreenReleased(); + } hw->releaseScreen(); getHwComposer().release(); mVisibleRegionsDirty = true; @@ -1801,7 +1845,8 @@ void SurfaceFlinger::unblank() { public: MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { } virtual bool handler() { - flinger->onScreenAcquired(); + // FIXME: should this be per-display? + flinger->onScreenAcquired(flinger->getDefaultDisplayDevice()); return true; } }; @@ -1815,7 +1860,8 @@ void SurfaceFlinger::blank() { public: MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { } virtual bool handler() { - flinger->onScreenReleased(); + // FIXME: should this be per-display? + flinger->onScreenReleased(flinger->getDefaultDisplayDevice()); return true; } }; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index ffe68c6d3..a6486219f 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -166,6 +166,7 @@ private: DisplayDeviceState(DisplayDevice::DisplayType type); bool isValid() const { return type >= 0; } bool isMainDisplay() const { return type == DisplayDevice::DISPLAY_PRIMARY; } + bool isVirtualDisplay() const { return type >= DisplayDevice::DISPLAY_VIRTUAL; } DisplayDevice::DisplayType type; sp surface; uint32_t layerStack; @@ -238,9 +239,9 @@ private: // called on the main thread in response to initializeDisplays() void onInitializeDisplays(); // called on the main thread in response to blank() - void onScreenReleased(); + void onScreenReleased(const sp& hw); // called on the main thread in response to unblank() - void onScreenAcquired(); + void onScreenAcquired(const sp& hw); void handleMessageTransaction(); void handleMessageInvalidate(); @@ -320,7 +321,7 @@ private: EGLint const* attrs, PixelFormat format, EGLConfig* outConfig); static EGLConfig selectEGLConfig(EGLDisplay disp, EGLint visualId); static EGLContext createGLContext(EGLDisplay disp, EGLConfig config); - void initializeGL(EGLDisplay display, const sp& hw); + void initializeGL(EGLDisplay display); uint32_t getMaxTextureSize() const; uint32_t getMaxViewportDims() const;