From 1e26087493ac0e7d7dc6dea8ad85cfef08b3271f Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 8 Aug 2012 18:35:12 -0700 Subject: [PATCH] Add a display parameter to HWComposer where needed - also replace C casts with C++ casts - only the interface is changed, HWComposer still doesn't fully handle multiple displays Change-Id: I48eb89bff2edb76bf1d4d41f46802b9b2a7166a8 --- services/surfaceflinger/DisplayDevice.h | 1 + .../DisplayHardware/HWComposer.cpp | 80 ++++++++++--------- .../DisplayHardware/HWComposer.h | 23 +++--- services/surfaceflinger/SurfaceFlinger.cpp | 56 +++++++------ 4 files changed, 89 insertions(+), 71 deletions(-) diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index 7efd3bc83..cb8fe2fc8 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -96,6 +96,7 @@ public: int getOrientation() const { return mOrientation; } const Transform& getTransform() const { return mGlobalTransform; } uint32_t getLayerStack() const { return mLayerStack; } + int32_t getDisplayId() const { return mId; } status_t compositionComplete() const; diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 40ce90b9a..909c30dcc 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -91,7 +91,7 @@ static int hwcEventControl(hwc_composer_device_1_t* hwc, int dpy, if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { return hwc->methods->eventControl(hwc, dpy, event, enabled); } else { - hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; + hwc_composer_device_t* hwc0 = reinterpret_cast(hwc); return hwc0->methods->eventControl(hwc0, event, enabled); } } @@ -101,7 +101,7 @@ static int hwcBlank(hwc_composer_device_1_t* hwc, int dpy, int blank) { return hwc->methods->blank(hwc, dpy, blank); } else { if (blank) { - hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; + hwc_composer_device_t* hwc0 = reinterpret_cast(hwc); return hwc0->set(hwc0, NULL, NULL, NULL); } else { // HWC 0.x turns the screen on at the next set() @@ -115,8 +115,8 @@ static int hwcPrepare(hwc_composer_device_1_t* hwc, if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { return hwc->prepare(hwc, numDisplays, displays); } else { - hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; - hwc_layer_list_t* list0 = (hwc_layer_list_t*)displays[0]; + hwc_composer_device_t* hwc0 = reinterpret_cast(hwc); + hwc_layer_list_t* list0 = reinterpret_cast(displays[0]); // In the past, SurfaceFlinger would pass a NULL list when doing full // OpenGL ES composition. I don't know what, if any, dependencies there // are on this behavior, so I'm playing it safe and preserving it. @@ -135,8 +135,8 @@ static int hwcSet(hwc_composer_device_1_t* hwc, EGLDisplay dpy, EGLSurface sur, displays[0]->sur = sur; err = hwc->set(hwc, numDisplays, displays); } else { - hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; - hwc_layer_list_t* list0 = (hwc_layer_list_t*)displays[0]; + hwc_composer_device_t* hwc0 = reinterpret_cast(hwc); + hwc_layer_list_t* list0 = reinterpret_cast(displays[0]); err = hwc0->set(hwc0, dpy, sur, list0); } return err; @@ -147,8 +147,7 @@ static uint32_t& hwcFlags(hwc_composer_device_1_t* hwc, if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { return display->flags; } else { - hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; - hwc_layer_list_t* list0 = (hwc_layer_list_t*)display; + hwc_layer_list_t* list0 = reinterpret_cast(display); return list0->flags; } } @@ -158,8 +157,7 @@ static size_t& hwcNumHwLayers(hwc_composer_device_1_t* hwc, if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { return display->numHwLayers; } else { - hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; - hwc_layer_list_t* list0 = (hwc_layer_list_t*)display; + hwc_layer_list_t* list0 = reinterpret_cast(display); return list0->numHwLayers; } } @@ -236,7 +234,7 @@ HWComposer::HWComposer( } // create initial empty display contents for display 0 - createWorkList(0); + createWorkList(MAIN, 0); } } @@ -332,8 +330,12 @@ void HWComposer::eventControl(int event, int enabled) { } } -status_t HWComposer::createWorkList(size_t numLayers) { +status_t HWComposer::createWorkList(int32_t id, size_t numLayers) { // FIXME: handle multiple displays + if (uint32_t(id) >= MAX_DISPLAYS) + return BAD_INDEX; + if (mHwc) { + // TODO: must handle multiple displays here // mLists[0] is NULL only when this is called from the constructor if (!mLists[0] || mCapacity < numLayers) { free(mLists[0]); @@ -356,21 +358,27 @@ status_t HWComposer::prepare() const { if (err == NO_ERROR) { size_t numOVLayers = 0; size_t numFBLayers = 0; - size_t count = getNumLayers(); + size_t count = getNumLayers(0); + for (size_t i=0 ; ihwLayers[i]; + hwc_layer_1_t* l = &mLists[0]->hwLayers[i]; + if (l->flags & HWC_SKIP_LAYER) { + l->compositionType = HWC_FRAMEBUFFER; + } + compositionType = l->compositionType; } else { // mList really has hwc_layer_list_t memory layout - hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0]; - hwc_layer_t* layer = &list0->hwLayers[i]; - l = (hwc_layer_1_t*)layer; + hwc_layer_list_t* list0 = reinterpret_cast(mLists[0]); + hwc_layer_t* l = &list0->hwLayers[i]; + if (l->flags & HWC_SKIP_LAYER) { + l->compositionType = HWC_FRAMEBUFFER; + } + compositionType = l->compositionType; } - if (l->flags & HWC_SKIP_LAYER) { - l->compositionType = HWC_FRAMEBUFFER; - } - switch (l->compositionType) { + + switch (compositionType) { case HWC_OVERLAY: numOVLayers++; break; @@ -385,7 +393,7 @@ status_t HWComposer::prepare() const { return (status_t)err; } -size_t HWComposer::getLayerCount(int type) const { +size_t HWComposer::getLayerCount(int32_t id, int type) const { // FIXME: handle multiple displays switch (type) { case HWC_OVERLAY: return mNumOVLayers; @@ -437,7 +445,7 @@ status_t HWComposer::disable() { return NO_ERROR; } -size_t HWComposer::getNumLayers() const { +size_t HWComposer::getNumLayers(int32_t id) const { // FIXME: handle multiple displays return mHwc ? hwcNumHwLayers(mHwc, mLists[0]) : 0; } @@ -611,14 +619,14 @@ public: /* * returns an iterator initialized at a given index in the layer list */ -HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) { +HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) { // FIXME: handle multiple displays if (index > hwcNumHwLayers(mHwc, mLists[0])) return LayerListIterator(); if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { return LayerListIterator(new HWCLayerVersion1(mLists[0]->hwLayers), index); } else { - hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0]; + hwc_layer_list_t* list0 = reinterpret_cast(mLists[0]); return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index); } } @@ -626,21 +634,21 @@ HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) { /* * returns an iterator on the beginning of the layer list */ -HWComposer::LayerListIterator HWComposer::begin() { - return getLayerIterator(0); +HWComposer::LayerListIterator HWComposer::begin(int32_t id) { // FIXME: handle multiple displays + return getLayerIterator(id, 0); } /* * returns an iterator on the end of the layer list */ -HWComposer::LayerListIterator HWComposer::end() { - return getLayerIterator(getNumLayers()); +HWComposer::LayerListIterator HWComposer::end(int32_t id) { // FIXME: handle multiple displays + return getLayerIterator(id, getNumLayers(id)); } void HWComposer::dump(String8& result, char* buffer, size_t SIZE, const Vector< sp >& visibleLayersSortedByZ) const { if (mHwc) { - hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0]; + hwc_layer_list_t* list0 = reinterpret_cast(mLists[0]); result.append("Hardware Composer state:\n"); result.appendFormat(" mDebugForceFakeVSync=%d\n", @@ -652,13 +660,12 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE, "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n"); // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____] for (size_t i=0 ; ihwLayers[i]; + lp = &mLists[0]->hwLayers[i]; } else { - hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0]; - *(hwc_layer_t*)&l = list0->hwLayers[i]; - l.acquireFenceFd = l.releaseFenceFd = -1; + // FIXME: here we rely on hwc_layer_1_t and hwc_layer_t having the same layout + lp = reinterpret_cast(&list0->hwLayers[i]); } const sp layer(visibleLayersSortedByZ[i]); int32_t format = -1; @@ -668,6 +675,7 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE, format = buffer->getPixelFormat(); } } + const hwc_layer_1_t& l(*lp); result.appendFormat( " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n", l.compositionType ? "OVERLAY" : "FB", diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 112e12067..52171f349 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -56,6 +56,12 @@ public: virtual ~EventHandler() {} }; + enum { + MAIN = 0, + HDMI = 1, + MAX_DISPLAYS + }; + HWComposer(const sp& flinger, EventHandler& handler); ~HWComposer(); @@ -77,14 +83,11 @@ public: status_t acquire() const; // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED. - status_t createWorkList(size_t numLayers); - - // get the layer array created by createWorkList() - size_t getNumLayers() const; + status_t createWorkList(int32_t id, size_t numLayers); // get number of layers of the given type as updated in prepare(). // type is HWC_OVERLAY or HWC_FRAMEBUFFER - size_t getLayerCount(int type) const; + size_t getLayerCount(int32_t id, int type) const; // needed forward declarations class LayerListIterator; @@ -175,10 +178,10 @@ public: }; // Returns an iterator to the beginning of the layer list - LayerListIterator begin(); + LayerListIterator begin(int32_t id); // Returns an iterator to the end of the layer list - LayerListIterator end(); + LayerListIterator end(int32_t id); // Events handling --------------------------------------------------------- @@ -215,9 +218,9 @@ public: const Vector< sp >& visibleLayersSortedByZ) const; private: - enum { MAX_DISPLAYS = 1 }; - LayerListIterator getLayerIterator(size_t index); + LayerListIterator getLayerIterator(int32_t id, size_t index); + size_t getNumLayers(int32_t id) const; struct cb_context; @@ -227,6 +230,7 @@ private: inline void invalidate(); inline void vsync(int dpy, int64_t timestamp); + sp mFlinger; hw_module_t const* mModule; struct hwc_composer_device_1* mHwc; @@ -234,6 +238,7 @@ private: // TODO: decide whether mLists[i>0] should be non-NULL when display i is // not attached/enabled. struct hwc_display_contents_1* mLists[MAX_DISPLAYS]; + size_t mCapacity; mutable size_t mNumOVLayers; mutable size_t mNumFBLayers; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1c15c82fc..f17a7d289 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -454,8 +454,8 @@ bool SurfaceFlinger::authenticateSurfaceTexture( } status_t SurfaceFlinger::getDisplayInfo(DisplayID dpy, DisplayInfo* info) { - // TODO: this is here only for compatibility -- show go away eventually. - if (uint32_t(dpy) >= 2) { + // TODO: this is here only for compatibility -- should go away eventually. + if (uint32_t(dpy) >= 1) { return BAD_INDEX; } sp hw(getDefaultDisplayDevice()); @@ -628,25 +628,26 @@ void SurfaceFlinger::handleMessageRefresh() { const Vector< sp >& currentLayers(hw->getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); - hwc.createWorkList(count); // FIXME: the worklist should include enough space for all layer of all displays + const int32_t id = hw->getDisplayId(); + if (hwc.createWorkList(id, count) >= 0) { + HWComposer::LayerListIterator cur = hwc.begin(id); + const HWComposer::LayerListIterator end = hwc.end(id); + for (size_t i=0 ; cur!=end && i& layer(currentLayers[i]); - HWComposer::LayerListIterator cur = hwc.begin(); - const HWComposer::LayerListIterator end = hwc.end(); - for (size_t i=0 ; cur!=end && i& layer(currentLayers[i]); - - if (CC_UNLIKELY(workListsDirty)) { - layer->setGeometry(hw, *cur); - if (mDebugDisableHWC || mDebugRegion) { - cur->setSkip(true); + if (CC_UNLIKELY(workListsDirty)) { + layer->setGeometry(hw, *cur); + if (mDebugDisableHWC || mDebugRegion) { + cur->setSkip(true); + } } - } - /* - * update the per-frame h/w composer data for each layer - * and build the transparent region of the FB - */ - layer->setPerFrameData(hw, *cur); + /* + * update the per-frame h/w composer data for each layer + * and build the transparent region of the FB + */ + layer->setPerFrameData(hw, *cur); + } } } status_t err = hwc.prepare(); @@ -738,8 +739,9 @@ void SurfaceFlinger::postFramebuffer() if (hwc.initCheck() == NO_ERROR) { const Vector< sp >& currentLayers(hw->getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); - HWComposer::LayerListIterator cur = hwc.begin(); - const HWComposer::LayerListIterator end = hwc.end(); + const int32_t id = hw->getDisplayId(); + HWComposer::LayerListIterator cur = hwc.begin(id); + const HWComposer::LayerListIterator end = hwc.end(id); for (size_t i=0 ; cur!=end && i& layer(currentLayers[i]); layer->setAcquireFence(hw, *cur); @@ -759,8 +761,9 @@ void SurfaceFlinger::postFramebuffer() const Vector< sp >& currentLayers(hw->getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); if (hwc.initCheck() == NO_ERROR) { - HWComposer::LayerListIterator cur = hwc.begin(); - const HWComposer::LayerListIterator end = hwc.end(); + int32_t id = hw->getDisplayId(); + HWComposer::LayerListIterator cur = hwc.begin(id); + const HWComposer::LayerListIterator end = hwc.end(id); for (size_t i = 0; cur != end && i < count; ++i, ++cur) { currentLayers[i]->onLayerDisplayed(hw, &*cur); } @@ -1152,10 +1155,11 @@ void SurfaceFlinger::handleRepaint(const sp& hw, void SurfaceFlinger::composeSurfaces(const sp& hw, const Region& dirty) { HWComposer& hwc(getHwComposer()); - HWComposer::LayerListIterator cur = hwc.begin(); - const HWComposer::LayerListIterator end = hwc.end(); + int32_t id = hw->getDisplayId(); + HWComposer::LayerListIterator cur = hwc.begin(id); + const HWComposer::LayerListIterator end = hwc.end(id); - const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); // FIXME: this should be per display + const size_t fbLayerCount = hwc.getLayerCount(id, HWC_FRAMEBUFFER); if (cur==end || fbLayerCount) { DisplayDevice::makeCurrent(hw, mEGLContext); @@ -1165,7 +1169,7 @@ void SurfaceFlinger::composeSurfaces(const sp& hw, const Re glLoadIdentity(); // Never touch the framebuffer if we don't have any framebuffer layers - if (hwc.getLayerCount(HWC_OVERLAY)) { // FIXME: this should be per display + if (hwc.getLayerCount(id, HWC_OVERLAY)) { // when using overlays, we assume a fully transparent framebuffer // NOTE: we could reduce how much we need to clear, for instance // remove where there are opaque FB layers. however, on some