Loading services/surfaceflinger/DisplayHardware/DisplayHardware.h +2 −1 Original line number Diff line number Diff line Loading @@ -84,9 +84,10 @@ public: status_t compositionComplete() const; Rect bounds() const { Rect getBounds() const { return Rect(mWidth, mHeight); } inline Rect bounds() const { return getBounds(); } // only for debugging int getCurrentBufferIndex() const; Loading services/surfaceflinger/DisplayHardware/HWComposer.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ namespace android { HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger) : mFlinger(flinger), mModule(0), mHwc(0), mList(0), mCapacity(0), mNumOVLayers(0), mNumFBLayers(0), mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE) { int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); Loading Loading @@ -98,9 +99,40 @@ status_t HWComposer::createWorkList(size_t numLayers) { status_t HWComposer::prepare() const { int err = mHwc->prepare(mHwc, mList); if (err == NO_ERROR) { size_t numOVLayers = 0; size_t numFBLayers = 0; size_t count = mList->numHwLayers; for (size_t i=0 ; i<count ; i++) { hwc_layer& l(mList->hwLayers[i]); if (l.flags & HWC_SKIP_LAYER) { l.compositionType = HWC_FRAMEBUFFER; } switch (l.compositionType) { case HWC_OVERLAY: numOVLayers++; break; case HWC_FRAMEBUFFER: numFBLayers++; break; } } mNumOVLayers = numOVLayers; mNumFBLayers = numFBLayers; } return (status_t)err; } size_t HWComposer::getLayerCount(int type) const { switch (type) { case HWC_OVERLAY: return mNumOVLayers; case HWC_FRAMEBUFFER: return mNumFBLayers; } return 0; } status_t HWComposer::commit() const { int err = mHwc->set(mHwc, mDpy, mSur, mList); if (mList) { Loading services/surfaceflinger/DisplayHardware/HWComposer.h +5 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,9 @@ public: size_t getNumLayers() const; hwc_layer_t* getLayers() const; // updated in preapre() size_t getLayerCount(int type) const; // for debugging void dump(String8& out, char* scratch, size_t SIZE, const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const; Loading @@ -81,6 +84,8 @@ private: hwc_composer_device_t* mHwc; hwc_layer_list_t* mList; size_t mCapacity; mutable size_t mNumOVLayers; mutable size_t mNumFBLayers; hwc_display_t mDpy; hwc_surface_t mSur; cb_context mCBContext; Loading services/surfaceflinger/SurfaceFlinger.cpp +50 −46 Original line number Diff line number Diff line Loading @@ -876,24 +876,21 @@ void SurfaceFlinger::handleRepaint() } } Region expandDirty = setupHardwareComposer(mDirtyRegion); mDirtyRegion.orSelf(expandDirty); mSwapRegion.orSelf(mDirtyRegion); setupHardwareComposer(mDirtyRegion); composeSurfaces(mDirtyRegion); // clear the dirty regions // update the swap region and clear the dirty region mSwapRegion.orSelf(mDirtyRegion); mDirtyRegion.clear(); } Region SurfaceFlinger::setupHardwareComposer(const Region& dirty) void SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut) { Region dirtyOut(dirty); const DisplayHardware& hw(graphicPlane(0).displayHardware()); HWComposer& hwc(hw.getHwComposer()); hwc_layer_t* const cur(hwc.getLayers()); if (!cur) { return dirtyOut; return; } const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); Loading @@ -916,12 +913,11 @@ Region SurfaceFlinger::setupHardwareComposer(const Region& dirty) const sp<LayerBase>& layer(layers[i]); layer->setPerFrameData(&cur[i]); } const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); status_t err = hwc.prepare(); LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); if (err == NO_ERROR) { Region transparent; for (size_t i=0 ; i<count ; i++) { // what's happening here is tricky. // we want to clear all the layers with the CLEAR_FB flags // that are opaque. Loading @@ -932,37 +928,47 @@ Region SurfaceFlinger::setupHardwareComposer(const Region& dirty) // NOTE: on non backbuffer preserving GPU, the dirty region // has already been expanded as needed, so the code is correct // there too. // // However, the content of the framebuffer cannot be trusted when // we switch to/from FB/OVERLAY, in which case we need to // expand the dirty region to those areas too. // // Note also that there is a special case when switching from // "no layers in FB" to "some layers in FB", where we need to redraw // the entire FB, since some areas might contain uninitialized // data. // // Also we want to make sure to not clear areas that belong to // layers above that won't redraw (we would just erasing them), // that is, we can't erase anything outside the dirty region. Region transparent; if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) { transparent.set(hw.getBounds()); dirtyInOut = transparent; } else { for (size_t i=0 ; i<count ; i++) { const sp<LayerBase>& layer(layers[i]); if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) { transparent.orSelf(layer->visibleRegionScreen); } bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER) && !(cur[i].flags & HWC_SKIP_LAYER); bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER); if (isOverlay != layer->isOverlay()) { // we transitioned to/from overlay, so add this layer // to the dirty region so the framebuffer can be either // cleared or redrawn. dirtyOut.orSelf(layer->visibleRegionScreen); dirtyInOut.orSelf(layer->visibleRegionScreen); } layer->setOverlay(isOverlay); } // don't erase stuff outside the dirty region transparent.andSelf(dirtyInOut); } /* * clear the area of the FB that need to be transparent */ // don't erase stuff outside the dirty region transparent.andSelf(dirtyOut); if (!transparent.isEmpty()) { glClearColor(0,0,0,0); Region::const_iterator it = transparent.begin(); Loading @@ -976,7 +982,6 @@ Region SurfaceFlinger::setupHardwareComposer(const Region& dirty) } } } return dirtyOut; } void SurfaceFlinger::composeSurfaces(const Region& dirty) Loading @@ -997,8 +1002,7 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty) const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); size_t count = layers.size(); for (size_t i=0 ; i<count ; i++) { if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER) && !(cur[i].flags & HWC_SKIP_LAYER)) { if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) { continue; } const sp<LayerBase>& layer(layers[i]); Loading services/surfaceflinger/SurfaceFlinger.h +1 −1 Original line number Diff line number Diff line Loading @@ -277,7 +277,7 @@ private: void handleWorkList(); void handleRepaint(); void postFramebuffer(); Region setupHardwareComposer(const Region& dirty); void setupHardwareComposer(Region& dirtyInOut); void composeSurfaces(const Region& dirty); void repaintEverything(); Loading Loading
services/surfaceflinger/DisplayHardware/DisplayHardware.h +2 −1 Original line number Diff line number Diff line Loading @@ -84,9 +84,10 @@ public: status_t compositionComplete() const; Rect bounds() const { Rect getBounds() const { return Rect(mWidth, mHeight); } inline Rect bounds() const { return getBounds(); } // only for debugging int getCurrentBufferIndex() const; Loading
services/surfaceflinger/DisplayHardware/HWComposer.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ namespace android { HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger) : mFlinger(flinger), mModule(0), mHwc(0), mList(0), mCapacity(0), mNumOVLayers(0), mNumFBLayers(0), mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE) { int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); Loading Loading @@ -98,9 +99,40 @@ status_t HWComposer::createWorkList(size_t numLayers) { status_t HWComposer::prepare() const { int err = mHwc->prepare(mHwc, mList); if (err == NO_ERROR) { size_t numOVLayers = 0; size_t numFBLayers = 0; size_t count = mList->numHwLayers; for (size_t i=0 ; i<count ; i++) { hwc_layer& l(mList->hwLayers[i]); if (l.flags & HWC_SKIP_LAYER) { l.compositionType = HWC_FRAMEBUFFER; } switch (l.compositionType) { case HWC_OVERLAY: numOVLayers++; break; case HWC_FRAMEBUFFER: numFBLayers++; break; } } mNumOVLayers = numOVLayers; mNumFBLayers = numFBLayers; } return (status_t)err; } size_t HWComposer::getLayerCount(int type) const { switch (type) { case HWC_OVERLAY: return mNumOVLayers; case HWC_FRAMEBUFFER: return mNumFBLayers; } return 0; } status_t HWComposer::commit() const { int err = mHwc->set(mHwc, mDpy, mSur, mList); if (mList) { Loading
services/surfaceflinger/DisplayHardware/HWComposer.h +5 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,9 @@ public: size_t getNumLayers() const; hwc_layer_t* getLayers() const; // updated in preapre() size_t getLayerCount(int type) const; // for debugging void dump(String8& out, char* scratch, size_t SIZE, const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const; Loading @@ -81,6 +84,8 @@ private: hwc_composer_device_t* mHwc; hwc_layer_list_t* mList; size_t mCapacity; mutable size_t mNumOVLayers; mutable size_t mNumFBLayers; hwc_display_t mDpy; hwc_surface_t mSur; cb_context mCBContext; Loading
services/surfaceflinger/SurfaceFlinger.cpp +50 −46 Original line number Diff line number Diff line Loading @@ -876,24 +876,21 @@ void SurfaceFlinger::handleRepaint() } } Region expandDirty = setupHardwareComposer(mDirtyRegion); mDirtyRegion.orSelf(expandDirty); mSwapRegion.orSelf(mDirtyRegion); setupHardwareComposer(mDirtyRegion); composeSurfaces(mDirtyRegion); // clear the dirty regions // update the swap region and clear the dirty region mSwapRegion.orSelf(mDirtyRegion); mDirtyRegion.clear(); } Region SurfaceFlinger::setupHardwareComposer(const Region& dirty) void SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut) { Region dirtyOut(dirty); const DisplayHardware& hw(graphicPlane(0).displayHardware()); HWComposer& hwc(hw.getHwComposer()); hwc_layer_t* const cur(hwc.getLayers()); if (!cur) { return dirtyOut; return; } const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); Loading @@ -916,12 +913,11 @@ Region SurfaceFlinger::setupHardwareComposer(const Region& dirty) const sp<LayerBase>& layer(layers[i]); layer->setPerFrameData(&cur[i]); } const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); status_t err = hwc.prepare(); LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); if (err == NO_ERROR) { Region transparent; for (size_t i=0 ; i<count ; i++) { // what's happening here is tricky. // we want to clear all the layers with the CLEAR_FB flags // that are opaque. Loading @@ -932,37 +928,47 @@ Region SurfaceFlinger::setupHardwareComposer(const Region& dirty) // NOTE: on non backbuffer preserving GPU, the dirty region // has already been expanded as needed, so the code is correct // there too. // // However, the content of the framebuffer cannot be trusted when // we switch to/from FB/OVERLAY, in which case we need to // expand the dirty region to those areas too. // // Note also that there is a special case when switching from // "no layers in FB" to "some layers in FB", where we need to redraw // the entire FB, since some areas might contain uninitialized // data. // // Also we want to make sure to not clear areas that belong to // layers above that won't redraw (we would just erasing them), // that is, we can't erase anything outside the dirty region. Region transparent; if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) { transparent.set(hw.getBounds()); dirtyInOut = transparent; } else { for (size_t i=0 ; i<count ; i++) { const sp<LayerBase>& layer(layers[i]); if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) { transparent.orSelf(layer->visibleRegionScreen); } bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER) && !(cur[i].flags & HWC_SKIP_LAYER); bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER); if (isOverlay != layer->isOverlay()) { // we transitioned to/from overlay, so add this layer // to the dirty region so the framebuffer can be either // cleared or redrawn. dirtyOut.orSelf(layer->visibleRegionScreen); dirtyInOut.orSelf(layer->visibleRegionScreen); } layer->setOverlay(isOverlay); } // don't erase stuff outside the dirty region transparent.andSelf(dirtyInOut); } /* * clear the area of the FB that need to be transparent */ // don't erase stuff outside the dirty region transparent.andSelf(dirtyOut); if (!transparent.isEmpty()) { glClearColor(0,0,0,0); Region::const_iterator it = transparent.begin(); Loading @@ -976,7 +982,6 @@ Region SurfaceFlinger::setupHardwareComposer(const Region& dirty) } } } return dirtyOut; } void SurfaceFlinger::composeSurfaces(const Region& dirty) Loading @@ -997,8 +1002,7 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty) const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); size_t count = layers.size(); for (size_t i=0 ; i<count ; i++) { if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER) && !(cur[i].flags & HWC_SKIP_LAYER)) { if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) { continue; } const sp<LayerBase>& layer(layers[i]); Loading
services/surfaceflinger/SurfaceFlinger.h +1 −1 Original line number Diff line number Diff line Loading @@ -277,7 +277,7 @@ private: void handleWorkList(); void handleRepaint(); void postFramebuffer(); Region setupHardwareComposer(const Region& dirty); void setupHardwareComposer(Region& dirtyInOut); void composeSurfaces(const Region& dirty); void repaintEverything(); Loading