Loading services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h +3 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,9 @@ public: // Takes (moves) the set of layers being released this frame. virtual ReleasedLayers takeReleasedLayers() = 0; // Signals that a frame is beginning on the output virtual void beginFrame() = 0; // Prepares a frame for display virtual void prepareFrame() = 0; Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h +1 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ public: void setReleasedLayers(ReleasedLayers&&) override; ReleasedLayers takeReleasedLayers() override; void beginFrame() override; void prepareFrame() override; void postFramebuffer() override; Loading services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h +1 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ public: MOCK_METHOD1(setReleasedLayers, void(ReleasedLayers&&)); MOCK_METHOD0(takeReleasedLayers, ReleasedLayers()); MOCK_METHOD0(beginFrame, void()); MOCK_METHOD0(prepareFrame, void()); MOCK_METHOD0(chooseCompositionStrategy, void()); Loading services/surfaceflinger/CompositionEngine/src/Output.cpp +28 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,34 @@ Output::ReleasedLayers Output::takeReleasedLayers() { return std::move(mReleasedLayers); } void Output::beginFrame() { const bool dirty = !getDirtyRegion(false).isEmpty(); const bool empty = mOutputLayersOrderedByZ.empty(); const bool wasEmpty = !mState.lastCompositionHadVisibleLayers; // If nothing has changed (!dirty), don't recompose. // If something changed, but we don't currently have any visible layers, // and didn't when we last did a composition, then skip it this time. // The second rule does two things: // - When all layers are removed from a display, we'll emit one black // frame, then nothing more until we get new layers. // - When a display is created with a private layer stack, we won't // emit any black frames until a layer is added to the layer stack. const bool mustRecompose = dirty && !(empty && wasEmpty); const char flagPrefix[] = {'-', '+'}; static_cast<void>(flagPrefix); ALOGV_IF("%s: %s composition for %s (%cdirty %cempty %cwasEmpty)", __FUNCTION__, mustRecompose ? "doing" : "skipping", getName().c_str(), flagPrefix[dirty], flagPrefix[empty], flagPrefix[wasEmpty]); mRenderSurface->beginFrame(mustRecompose); if (mustRecompose) { mState.lastCompositionHadVisibleLayers = !empty; } } void Output::prepareFrame() { ATRACE_CALL(); ALOGV(__FUNCTION__); Loading services/surfaceflinger/SurfaceFlinger.cpp +6 −37 Original line number Diff line number Diff line Loading @@ -1790,11 +1790,12 @@ void SurfaceFlinger::handleMessageRefresh() { mCompositionEngine->preComposition(refreshArgs); rebuildLayerStacks(); calculateWorkingSet(); for (const auto& [token, display] : mDisplays) { beginFrame(display); display->getCompositionDisplay()->prepareFrame(); doDebugFlashRegions(display, repaintEverything); doComposition(display, repaintEverything); for (const auto& [token, displayDevice] : mDisplays) { auto display = displayDevice->getCompositionDisplay(); display->beginFrame(); display->prepareFrame(); doDebugFlashRegions(displayDevice, repaintEverything); doComposition(displayDevice, repaintEverything); } logLayerStats(); Loading Loading @@ -2373,38 +2374,6 @@ void SurfaceFlinger::pickColorMode(const sp<DisplayDevice>& display, ColorMode* profile->getBestColorMode(bestDataSpace, intent, outDataSpace, outMode, outRenderIntent); } void SurfaceFlinger::beginFrame(const sp<DisplayDevice>& displayDevice) { auto display = displayDevice->getCompositionDisplay(); const auto& displayState = display->getState(); bool dirty = !display->getDirtyRegion(false).isEmpty(); bool empty = displayDevice->getVisibleLayersSortedByZ().size() == 0; bool wasEmpty = !displayState.lastCompositionHadVisibleLayers; // If nothing has changed (!dirty), don't recompose. // If something changed, but we don't currently have any visible layers, // and didn't when we last did a composition, then skip it this time. // The second rule does two things: // - When all layers are removed from a display, we'll emit one black // frame, then nothing more until we get new layers. // - When a display is created with a private layer stack, we won't // emit any black frames until a layer is added to the layer stack. bool mustRecompose = dirty && !(empty && wasEmpty); const char flagPrefix[] = {'-', '+'}; static_cast<void>(flagPrefix); ALOGV_IF(displayDevice->isVirtual(), "%s: %s composition for %s (%cdirty %cempty %cwasEmpty)", __FUNCTION__, mustRecompose ? "doing" : "skipping", displayDevice->getDebugName().c_str(), flagPrefix[dirty], flagPrefix[empty], flagPrefix[wasEmpty]); display->getRenderSurface()->beginFrame(mustRecompose); if (mustRecompose) { display->editState().lastCompositionHadVisibleLayers = !empty; } } void SurfaceFlinger::doComposition(const sp<DisplayDevice>& displayDevice, bool repaintEverything) { ATRACE_CALL(); ALOGV("doComposition"); Loading Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h +3 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,9 @@ public: // Takes (moves) the set of layers being released this frame. virtual ReleasedLayers takeReleasedLayers() = 0; // Signals that a frame is beginning on the output virtual void beginFrame() = 0; // Prepares a frame for display virtual void prepareFrame() = 0; Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h +1 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ public: void setReleasedLayers(ReleasedLayers&&) override; ReleasedLayers takeReleasedLayers() override; void beginFrame() override; void prepareFrame() override; void postFramebuffer() override; Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h +1 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ public: MOCK_METHOD1(setReleasedLayers, void(ReleasedLayers&&)); MOCK_METHOD0(takeReleasedLayers, ReleasedLayers()); MOCK_METHOD0(beginFrame, void()); MOCK_METHOD0(prepareFrame, void()); MOCK_METHOD0(chooseCompositionStrategy, void()); Loading
services/surfaceflinger/CompositionEngine/src/Output.cpp +28 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,34 @@ Output::ReleasedLayers Output::takeReleasedLayers() { return std::move(mReleasedLayers); } void Output::beginFrame() { const bool dirty = !getDirtyRegion(false).isEmpty(); const bool empty = mOutputLayersOrderedByZ.empty(); const bool wasEmpty = !mState.lastCompositionHadVisibleLayers; // If nothing has changed (!dirty), don't recompose. // If something changed, but we don't currently have any visible layers, // and didn't when we last did a composition, then skip it this time. // The second rule does two things: // - When all layers are removed from a display, we'll emit one black // frame, then nothing more until we get new layers. // - When a display is created with a private layer stack, we won't // emit any black frames until a layer is added to the layer stack. const bool mustRecompose = dirty && !(empty && wasEmpty); const char flagPrefix[] = {'-', '+'}; static_cast<void>(flagPrefix); ALOGV_IF("%s: %s composition for %s (%cdirty %cempty %cwasEmpty)", __FUNCTION__, mustRecompose ? "doing" : "skipping", getName().c_str(), flagPrefix[dirty], flagPrefix[empty], flagPrefix[wasEmpty]); mRenderSurface->beginFrame(mustRecompose); if (mustRecompose) { mState.lastCompositionHadVisibleLayers = !empty; } } void Output::prepareFrame() { ATRACE_CALL(); ALOGV(__FUNCTION__); Loading
services/surfaceflinger/SurfaceFlinger.cpp +6 −37 Original line number Diff line number Diff line Loading @@ -1790,11 +1790,12 @@ void SurfaceFlinger::handleMessageRefresh() { mCompositionEngine->preComposition(refreshArgs); rebuildLayerStacks(); calculateWorkingSet(); for (const auto& [token, display] : mDisplays) { beginFrame(display); display->getCompositionDisplay()->prepareFrame(); doDebugFlashRegions(display, repaintEverything); doComposition(display, repaintEverything); for (const auto& [token, displayDevice] : mDisplays) { auto display = displayDevice->getCompositionDisplay(); display->beginFrame(); display->prepareFrame(); doDebugFlashRegions(displayDevice, repaintEverything); doComposition(displayDevice, repaintEverything); } logLayerStats(); Loading Loading @@ -2373,38 +2374,6 @@ void SurfaceFlinger::pickColorMode(const sp<DisplayDevice>& display, ColorMode* profile->getBestColorMode(bestDataSpace, intent, outDataSpace, outMode, outRenderIntent); } void SurfaceFlinger::beginFrame(const sp<DisplayDevice>& displayDevice) { auto display = displayDevice->getCompositionDisplay(); const auto& displayState = display->getState(); bool dirty = !display->getDirtyRegion(false).isEmpty(); bool empty = displayDevice->getVisibleLayersSortedByZ().size() == 0; bool wasEmpty = !displayState.lastCompositionHadVisibleLayers; // If nothing has changed (!dirty), don't recompose. // If something changed, but we don't currently have any visible layers, // and didn't when we last did a composition, then skip it this time. // The second rule does two things: // - When all layers are removed from a display, we'll emit one black // frame, then nothing more until we get new layers. // - When a display is created with a private layer stack, we won't // emit any black frames until a layer is added to the layer stack. bool mustRecompose = dirty && !(empty && wasEmpty); const char flagPrefix[] = {'-', '+'}; static_cast<void>(flagPrefix); ALOGV_IF(displayDevice->isVirtual(), "%s: %s composition for %s (%cdirty %cempty %cwasEmpty)", __FUNCTION__, mustRecompose ? "doing" : "skipping", displayDevice->getDebugName().c_str(), flagPrefix[dirty], flagPrefix[empty], flagPrefix[wasEmpty]); display->getRenderSurface()->beginFrame(mustRecompose); if (mustRecompose) { display->editState().lastCompositionHadVisibleLayers = !empty; } } void SurfaceFlinger::doComposition(const sp<DisplayDevice>& displayDevice, bool repaintEverything) { ATRACE_CALL(); ALOGV("doComposition"); Loading