Loading services/surfaceflinger/LayerBase.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,14 @@ void LayerBase::setPerFrameData(hwc_layer_t* hwcl) { hwcl->handle = NULL; } void LayerBase::setOverlay(bool inOverlay) { mInOverlay = inOverlay; } bool LayerBase::isOverlay() const { return mInOverlay; } void LayerBase::setFiltering(bool filtering) { mFiltering = filtering; Loading services/surfaceflinger/LayerBase.h +8 −1 Original line number Diff line number Diff line Loading @@ -109,8 +109,10 @@ public: virtual const char* getTypeId() const { return "LayerBase"; } virtual void setGeometry(hwc_layer_t* hwcl); virtual void setPerFrameData(hwc_layer_t* hwcl); void setOverlay(bool inOverlay); bool isOverlay() const; /** * draw - performs some global clipping optimizations Loading Loading @@ -242,6 +244,11 @@ private: // Whether filtering is needed b/c of the drawingstate bool mNeedsFiltering; // this layer is currently handled by the hwc. this is // updated at composition time, always frmo the composition // thread. bool mInOverlay; protected: // cached during validateVisibility() int32_t mOrientation; Loading services/surfaceflinger/SurfaceFlinger.cpp +68 −59 Original line number Diff line number Diff line Loading @@ -817,20 +817,6 @@ void SurfaceFlinger::handleWorkList() mHwWorkListDirty = false; HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); if (hwc.initCheck() == NO_ERROR) { const DisplayHardware& hw(graphicPlane(0).displayHardware()); uint32_t flags = hw.getFlags(); if ((flags & DisplayHardware::SWAP_RECTANGLE) || (flags & DisplayHardware::BUFFER_PRESERVED)) { // we need to redraw everything (the whole screen) // NOTE: we could be more subtle here and redraw only // the area which will end-up in an overlay. But since this // shouldn't happen often, we invalidate everything. mDirtyRegion.set(hw.bounds()); mInvalidRegion = mDirtyRegion; } const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); const size_t count = currentLayers.size(); hwc.createWorkList(count); Loading Loading @@ -891,29 +877,26 @@ void SurfaceFlinger::handleRepaint() } // compose all surfaces setupHardwareComposer(&mDirtyRegion); composeSurfaces(mDirtyRegion); // clear the dirty regions mDirtyRegion.clear(); } void SurfaceFlinger::composeSurfaces(const Region& dirty) void SurfaceFlinger::setupHardwareComposer(Region* dirtyInOut) { if (UNLIKELY(!mWormholeRegion.isEmpty())) { // should never happen unless the window manager has a bug // draw something... drawWormhole(); const DisplayHardware& hw(graphicPlane(0).displayHardware()); HWComposer& hwc(hw.getHwComposer()); hwc_layer_t* const cur(hwc.getLayers()); if (!cur) { return; } status_t err = NO_ERROR; const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); size_t count = layers.size(); const DisplayHardware& hw(graphicPlane(0).displayHardware()); HWComposer& hwc(hw.getHwComposer()); hwc_layer_t* const cur(hwc.getLayers()); LOGE_IF(cur && hwc.getNumLayers() != count, LOGE_IF(hwc.getNumLayers() != count, "HAL number of layers (%d) doesn't match surfaceflinger (%d)", hwc.getNumLayers(), count); Loading @@ -927,28 +910,45 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty) * and build the transparent region of the FB */ Region transparent; if (cur) { for (size_t i=0 ; i<count ; i++) { const sp<LayerBase>& layer(layers[i]); layer->setPerFrameData(&cur[i]); } err = hwc.prepare(); status_t err = hwc.prepare(); LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); if (err == NO_ERROR) { Region transparentDirty(*dirtyInOut); for (size_t i=0 ; i<count ; i++) { if (cur[i].hints & HWC_HINT_CLEAR_FB) { // Calculate the new transparent region and dirty region // - the transparent region needs to always include the layers // that moved from FB to OVERLAY, regardless of the dirty region // - the dirty region needs to be expanded to include layers // that moved from OVERLAY to FB. const sp<LayerBase>& layer(layers[i]); if (layer->isOpaque()) { 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); if (!isOverlay && layer->isOverlay()) { dirtyInOut->orSelf(layer->visibleRegionScreen); } if (isOverlay && !layer->isOverlay()) { transparentDirty.orSelf(layer->visibleRegionScreen); } layer->setOverlay(isOverlay); } /* * clear the area of the FB that need to be transparent */ transparent.andSelf(dirty); transparent.andSelf(transparentDirty); if (!transparent.isEmpty()) { glClearColor(0,0,0,0); Region::const_iterator it = transparent.begin(); Loading @@ -964,19 +964,28 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty) } } void SurfaceFlinger::composeSurfaces(const Region& dirty) { if (UNLIKELY(!mWormholeRegion.isEmpty())) { // should never happen unless the window manager has a bug // draw something... drawWormhole(); } const DisplayHardware& hw(graphicPlane(0).displayHardware()); HWComposer& hwc(hw.getHwComposer()); hwc_layer_t* const cur(hwc.getLayers()); /* * and then, render the layers targeted at the framebuffer */ const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); size_t count = layers.size(); for (size_t i=0 ; i<count ; i++) { if (cur) { if ((cur[i].compositionType != HWC_FRAMEBUFFER) && if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER) && !(cur[i].flags & HWC_SKIP_LAYER)) { // skip layers handled by the HAL continue; } } const sp<LayerBase>& layer(layers[i]); const Region clip(dirty.intersect(layer->visibleRegionScreen)); if (!clip.isEmpty()) { Loading services/surfaceflinger/SurfaceFlinger.h +1 −0 Original line number Diff line number Diff line Loading @@ -277,6 +277,7 @@ private: void handleWorkList(); void handleRepaint(); void postFramebuffer(); void setupHardwareComposer(Region* dirtyInOut); void composeSurfaces(const Region& dirty); void repaintEverything(); Loading Loading
services/surfaceflinger/LayerBase.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,14 @@ void LayerBase::setPerFrameData(hwc_layer_t* hwcl) { hwcl->handle = NULL; } void LayerBase::setOverlay(bool inOverlay) { mInOverlay = inOverlay; } bool LayerBase::isOverlay() const { return mInOverlay; } void LayerBase::setFiltering(bool filtering) { mFiltering = filtering; Loading
services/surfaceflinger/LayerBase.h +8 −1 Original line number Diff line number Diff line Loading @@ -109,8 +109,10 @@ public: virtual const char* getTypeId() const { return "LayerBase"; } virtual void setGeometry(hwc_layer_t* hwcl); virtual void setPerFrameData(hwc_layer_t* hwcl); void setOverlay(bool inOverlay); bool isOverlay() const; /** * draw - performs some global clipping optimizations Loading Loading @@ -242,6 +244,11 @@ private: // Whether filtering is needed b/c of the drawingstate bool mNeedsFiltering; // this layer is currently handled by the hwc. this is // updated at composition time, always frmo the composition // thread. bool mInOverlay; protected: // cached during validateVisibility() int32_t mOrientation; Loading
services/surfaceflinger/SurfaceFlinger.cpp +68 −59 Original line number Diff line number Diff line Loading @@ -817,20 +817,6 @@ void SurfaceFlinger::handleWorkList() mHwWorkListDirty = false; HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); if (hwc.initCheck() == NO_ERROR) { const DisplayHardware& hw(graphicPlane(0).displayHardware()); uint32_t flags = hw.getFlags(); if ((flags & DisplayHardware::SWAP_RECTANGLE) || (flags & DisplayHardware::BUFFER_PRESERVED)) { // we need to redraw everything (the whole screen) // NOTE: we could be more subtle here and redraw only // the area which will end-up in an overlay. But since this // shouldn't happen often, we invalidate everything. mDirtyRegion.set(hw.bounds()); mInvalidRegion = mDirtyRegion; } const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); const size_t count = currentLayers.size(); hwc.createWorkList(count); Loading Loading @@ -891,29 +877,26 @@ void SurfaceFlinger::handleRepaint() } // compose all surfaces setupHardwareComposer(&mDirtyRegion); composeSurfaces(mDirtyRegion); // clear the dirty regions mDirtyRegion.clear(); } void SurfaceFlinger::composeSurfaces(const Region& dirty) void SurfaceFlinger::setupHardwareComposer(Region* dirtyInOut) { if (UNLIKELY(!mWormholeRegion.isEmpty())) { // should never happen unless the window manager has a bug // draw something... drawWormhole(); const DisplayHardware& hw(graphicPlane(0).displayHardware()); HWComposer& hwc(hw.getHwComposer()); hwc_layer_t* const cur(hwc.getLayers()); if (!cur) { return; } status_t err = NO_ERROR; const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); size_t count = layers.size(); const DisplayHardware& hw(graphicPlane(0).displayHardware()); HWComposer& hwc(hw.getHwComposer()); hwc_layer_t* const cur(hwc.getLayers()); LOGE_IF(cur && hwc.getNumLayers() != count, LOGE_IF(hwc.getNumLayers() != count, "HAL number of layers (%d) doesn't match surfaceflinger (%d)", hwc.getNumLayers(), count); Loading @@ -927,28 +910,45 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty) * and build the transparent region of the FB */ Region transparent; if (cur) { for (size_t i=0 ; i<count ; i++) { const sp<LayerBase>& layer(layers[i]); layer->setPerFrameData(&cur[i]); } err = hwc.prepare(); status_t err = hwc.prepare(); LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); if (err == NO_ERROR) { Region transparentDirty(*dirtyInOut); for (size_t i=0 ; i<count ; i++) { if (cur[i].hints & HWC_HINT_CLEAR_FB) { // Calculate the new transparent region and dirty region // - the transparent region needs to always include the layers // that moved from FB to OVERLAY, regardless of the dirty region // - the dirty region needs to be expanded to include layers // that moved from OVERLAY to FB. const sp<LayerBase>& layer(layers[i]); if (layer->isOpaque()) { 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); if (!isOverlay && layer->isOverlay()) { dirtyInOut->orSelf(layer->visibleRegionScreen); } if (isOverlay && !layer->isOverlay()) { transparentDirty.orSelf(layer->visibleRegionScreen); } layer->setOverlay(isOverlay); } /* * clear the area of the FB that need to be transparent */ transparent.andSelf(dirty); transparent.andSelf(transparentDirty); if (!transparent.isEmpty()) { glClearColor(0,0,0,0); Region::const_iterator it = transparent.begin(); Loading @@ -964,19 +964,28 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty) } } void SurfaceFlinger::composeSurfaces(const Region& dirty) { if (UNLIKELY(!mWormholeRegion.isEmpty())) { // should never happen unless the window manager has a bug // draw something... drawWormhole(); } const DisplayHardware& hw(graphicPlane(0).displayHardware()); HWComposer& hwc(hw.getHwComposer()); hwc_layer_t* const cur(hwc.getLayers()); /* * and then, render the layers targeted at the framebuffer */ const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); size_t count = layers.size(); for (size_t i=0 ; i<count ; i++) { if (cur) { if ((cur[i].compositionType != HWC_FRAMEBUFFER) && if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER) && !(cur[i].flags & HWC_SKIP_LAYER)) { // skip layers handled by the HAL continue; } } const sp<LayerBase>& layer(layers[i]); const Region clip(dirty.intersect(layer->visibleRegionScreen)); if (!clip.isEmpty()) { Loading
services/surfaceflinger/SurfaceFlinger.h +1 −0 Original line number Diff line number Diff line Loading @@ -277,6 +277,7 @@ private: void handleWorkList(); void handleRepaint(); void postFramebuffer(); void setupHardwareComposer(Region* dirtyInOut); void composeSurfaces(const Region& dirty); void repaintEverything(); Loading