diff options
11 files changed, 365 insertions, 211 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h index 3830b0743c..48d1471837 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h @@ -17,9 +17,12 @@ #pragma once #include <cstdint> +#include <iterator> #include <optional> #include <string> +#include <type_traits> #include <unordered_map> +#include <utility> #include <compositionengine/LayerFE.h> #include <renderengine/LayerSettings.h> @@ -55,10 +58,67 @@ struct OutputCompositionState; */ class Output { public: - using OutputLayers = std::vector<std::unique_ptr<compositionengine::OutputLayer>>; using ReleasedLayers = std::vector<wp<LayerFE>>; using UniqueFELayerStateMap = std::unordered_map<LayerFE*, LayerFECompositionState*>; + // A helper class for enumerating the output layers using a C++11 ranged-based for loop + template <typename T> + class OutputLayersEnumerator { + public: + // TODO(lpique): Consider turning this into a C++20 view when possible. + template <bool IsConstIter> + class IteratorImpl { + public: + // Required definitions to be considered an iterator + using iterator_category = std::forward_iterator_tag; + using value_type = decltype(std::declval<T>().getOutputLayerOrderedByZByIndex(0)); + using difference_type = std::ptrdiff_t; + using pointer = std::conditional_t<IsConstIter, const value_type*, value_type*>; + using reference = std::conditional_t<IsConstIter, const value_type&, value_type&>; + + IteratorImpl() = default; + IteratorImpl(const T* output, size_t index) : mOutput(output), mIndex(index) {} + + value_type operator*() const { + return mOutput->getOutputLayerOrderedByZByIndex(mIndex); + } + value_type operator->() const { + return mOutput->getOutputLayerOrderedByZByIndex(mIndex); + } + + bool operator==(const IteratorImpl& other) const { + return mOutput == other.mOutput && mIndex == other.mIndex; + } + bool operator!=(const IteratorImpl& other) const { return !operator==(other); } + + IteratorImpl& operator++() { + ++mIndex; + return *this; + } + IteratorImpl operator++(int) { + auto prev = *this; + ++mIndex; + return prev; + } + + private: + const T* mOutput{nullptr}; + size_t mIndex{0}; + }; + + using iterator = IteratorImpl<false>; + using const_iterator = IteratorImpl<true>; + + explicit OutputLayersEnumerator(const T& output) : mOutput(output) {} + auto begin() const { return iterator(&mOutput, 0); } + auto end() const { return iterator(&mOutput, mOutput.getOutputLayerCount()); } + auto cbegin() const { return const_iterator(&mOutput, 0); } + auto cend() const { return const_iterator(&mOutput, mOutput.getOutputLayerCount()); } + + private: + const T& mOutput; + }; + struct FrameFences { sp<Fence> presentFence{Fence::NO_FENCE}; sp<Fence> clientTargetAcquireFence{Fence::NO_FENCE}; @@ -152,28 +212,32 @@ public: virtual bool belongsInOutput(std::optional<uint32_t> layerStackId, bool internalOnly) const = 0; // Determines if a layer belongs to the output. - virtual bool belongsInOutput(const compositionengine::Layer*) const = 0; + virtual bool belongsInOutput(const Layer*) const = 0; // Returns a pointer to the output layer corresponding to the given layer on // this output, or nullptr if the layer does not have one virtual OutputLayer* getOutputLayerForLayer(Layer*) const = 0; - // Creates an OutputLayer instance for this output - virtual std::unique_ptr<OutputLayer> createOutputLayer(const std::shared_ptr<Layer>&, - const sp<LayerFE>&) const = 0; + // Immediately clears all layers from the output. + virtual void clearOutputLayers() = 0; + + // For tests use only. Creates and appends an OutputLayer into the output. + virtual OutputLayer* injectOutputLayerForTest(const std::shared_ptr<Layer>&, + const sp<LayerFE>&) = 0; - // Sets the new ordered set of output layers for this output - virtual void setOutputLayersOrderedByZ(OutputLayers&&) = 0; + // Gets the count of output layers managed by this output + virtual size_t getOutputLayerCount() const = 0; - // Gets the ordered set of output layers for this output - virtual const OutputLayers& getOutputLayersOrderedByZ() const = 0; + // Gets an output layer in Z order given its index + virtual OutputLayer* getOutputLayerOrderedByZByIndex(size_t) const = 0; + + // A helper function for enumerating all the output layers in Z order using + // a C++11 range-based for loop. + auto getOutputLayersOrderedByZ() const { return OutputLayersEnumerator(*this); } // Sets the new set of layers being released this frame virtual void setReleasedLayers(ReleasedLayers&&) = 0; - // Takes (moves) the set of layers being released this frame. - virtual ReleasedLayers takeReleasedLayers() = 0; - // Prepare the output, updating the OutputLayers used in the output virtual void prepare(const CompositionRefreshArgs&, LayerFESet&) = 0; @@ -187,12 +251,10 @@ protected: virtual void setDisplayColorProfile(std::unique_ptr<DisplayColorProfile>) = 0; virtual void setRenderSurface(std::unique_ptr<RenderSurface>) = 0; - virtual void rebuildLayerStacks(const compositionengine::CompositionRefreshArgs&, - LayerFESet&) = 0; + virtual void rebuildLayerStacks(const CompositionRefreshArgs&, LayerFESet&) = 0; virtual void collectVisibleLayers(const CompositionRefreshArgs&, CoverageState&) = 0; - virtual std::unique_ptr<OutputLayer> getOutputLayerIfVisible( - std::shared_ptr<compositionengine::Layer>, CoverageState&) = 0; - virtual void setReleasedLayers(const compositionengine::CompositionRefreshArgs&) = 0; + virtual void ensureOutputLayerIfVisible(std::shared_ptr<Layer>, CoverageState&) = 0; + virtual void setReleasedLayers(const CompositionRefreshArgs&) = 0; virtual void updateAndWriteCompositionState(const CompositionRefreshArgs&) = 0; virtual void setColorTransform(const CompositionRefreshArgs&) = 0; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h index 45a604ffeb..4acaab97e7 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h @@ -41,8 +41,6 @@ public: // compositionengine::Output overrides void dump(std::string&) const override; - std::unique_ptr<compositionengine::OutputLayer> createOutputLayer( - const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&) const override; using compositionengine::impl::Output::setReleasedLayers; void setReleasedLayers(const CompositionRefreshArgs&) override; void setColorTransform(const CompositionRefreshArgs&) override; @@ -72,6 +70,10 @@ public: virtual void applyDisplayRequests(const DisplayRequests&); virtual void applyLayerRequestsToLayers(const LayerRequests&); + // Internal + std::unique_ptr<compositionengine::OutputLayer> createOutputLayer( + const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&) const; + private: const bool mIsVirtual; std::optional<DisplayId> mId; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h index 27665727a6..ba6f72f522 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h @@ -60,13 +60,8 @@ public: compositionengine::OutputLayer* getOutputLayerForLayer( compositionengine::Layer*) const override; - std::unique_ptr<compositionengine::OutputLayer> createOutputLayer( - const std::shared_ptr<Layer>&, const sp<LayerFE>&) const override; - void setOutputLayersOrderedByZ(OutputLayers&&) override; - const OutputLayers& getOutputLayersOrderedByZ() const override; void setReleasedLayers(ReleasedLayers&&) override; - ReleasedLayers takeReleasedLayers() override; void prepare(const CompositionRefreshArgs&, LayerFESet&) override; void present(const CompositionRefreshArgs&) override; @@ -74,9 +69,8 @@ public: void rebuildLayerStacks(const CompositionRefreshArgs&, LayerFESet&) override; void collectVisibleLayers(const CompositionRefreshArgs&, compositionengine::Output::CoverageState&) override; - std::unique_ptr<compositionengine::OutputLayer> getOutputLayerIfVisible( - std::shared_ptr<compositionengine::Layer>, - compositionengine::Output::CoverageState&) override; + void ensureOutputLayerIfVisible(std::shared_ptr<compositionengine::Layer>, + compositionengine::Output::CoverageState&) override; void setReleasedLayers(const compositionengine::CompositionRefreshArgs&) override; void updateLayerStateFromFE(const CompositionRefreshArgs&) const override; @@ -95,9 +89,9 @@ public: void setRenderSurfaceForTest(std::unique_ptr<compositionengine::RenderSurface>); protected: - virtual const CompositionEngine& getCompositionEngine() const = 0; - std::unique_ptr<compositionengine::OutputLayer> takeOutputLayerForLayer( - compositionengine::Layer*); + std::unique_ptr<compositionengine::OutputLayer> createOutputLayer( + const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&) const; + std::optional<size_t> findCurrentOutputLayerForLayer(compositionengine::Layer*) const; void chooseCompositionStrategy() override; bool getSkipColorTransform() const override; compositionengine::Output::FrameFences presentAndGetFrameFences() override; @@ -109,7 +103,14 @@ protected: void dumpBase(std::string&) const; // Implemented by the final implementation for the final state it uses. - virtual void dumpState(std::string&) const = 0; + virtual compositionengine::OutputLayer* ensureOutputLayer( + std::optional<size_t>, const std::shared_ptr<compositionengine::Layer>&, + const sp<LayerFE>&) = 0; + virtual compositionengine::OutputLayer* injectOutputLayerForTest( + const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&) = 0; + virtual void finalizePendingOutputLayers() = 0; + virtual const compositionengine::CompositionEngine& getCompositionEngine() const = 0; + virtual void dumpState(std::string& out) const = 0; private: void dirtyEntireOutput(); @@ -122,7 +123,6 @@ private: std::unique_ptr<compositionengine::DisplayColorProfile> mDisplayColorProfile; std::unique_ptr<compositionengine::RenderSurface> mRenderSurface; - OutputLayers mOutputLayersOrderedByZ; ReleasedLayers mReleasedLayers; }; @@ -141,6 +141,8 @@ std::shared_ptr<BaseOutput> createOutputTemplated(const CompositionEngine& compo using OutputCompositionState = std::remove_const_t< std::remove_reference_t<decltype(std::declval<BaseOutput>().getState())>>; + using OutputLayer = std::remove_pointer_t<decltype( + std::declval<BaseOutput>().getOutputLayerOrderedByZByIndex(0))>; #pragma clang diagnostic pop @@ -151,16 +153,72 @@ std::shared_ptr<BaseOutput> createOutputTemplated(const CompositionEngine& compo private: // compositionengine::Output overrides const OutputCompositionState& getState() const override { return mState; } + OutputCompositionState& editState() override { return mState; } + size_t getOutputLayerCount() const override { + return mCurrentOutputLayersOrderedByZ.size(); + } + + OutputLayer* getOutputLayerOrderedByZByIndex(size_t index) const override { + if (index >= mCurrentOutputLayersOrderedByZ.size()) { + return nullptr; + } + return mCurrentOutputLayersOrderedByZ[index].get(); + } + // compositionengine::impl::Output overrides const CompositionEngine& getCompositionEngine() const override { return mCompositionEngine; }; + + OutputLayer* ensureOutputLayer(std::optional<size_t> prevIndex, + const std::shared_ptr<compositionengine::Layer>& layer, + const sp<LayerFE>& layerFE) { + auto outputLayer = (prevIndex && *prevIndex <= mCurrentOutputLayersOrderedByZ.size()) + ? std::move(mCurrentOutputLayersOrderedByZ[*prevIndex]) + : BaseOutput::createOutputLayer(layer, layerFE); + auto result = outputLayer.get(); + mPendingOutputLayersOrderedByZ.emplace_back(std::move(outputLayer)); + return result; + } + + void finalizePendingOutputLayers() override { + // The pending layers are added in reverse order. Reverse them to + // get the back-to-front ordered list of layers. + std::reverse(mPendingOutputLayersOrderedByZ.begin(), + mPendingOutputLayersOrderedByZ.end()); + + mCurrentOutputLayersOrderedByZ = std::move(mPendingOutputLayersOrderedByZ); + } + void dumpState(std::string& out) const override { mState.dump(out); } + OutputLayer* injectOutputLayerForTest( + const std::shared_ptr<compositionengine::Layer>& layer, + const sp<LayerFE>& layerFE) override { + auto outputLayer = BaseOutput::createOutputLayer(layer, layerFE); + auto result = outputLayer.get(); + mCurrentOutputLayersOrderedByZ.emplace_back(std::move(outputLayer)); + return result; + } + + // Note: This is declared as a private virtual non-override so it can be + // an override implementation in the unit tests, but otherwise is not an + // accessible override for the normal implementation. + virtual void injectOutputLayerForTest(std::unique_ptr<OutputLayer> outputLayer) { + mCurrentOutputLayersOrderedByZ.emplace_back(std::move(outputLayer)); + } + + void clearOutputLayers() override { + mCurrentOutputLayersOrderedByZ.clear(); + mPendingOutputLayersOrderedByZ.clear(); + } + const CompositionEngine& mCompositionEngine; OutputCompositionState mState; + std::vector<std::unique_ptr<OutputLayer>> mCurrentOutputLayersOrderedByZ; + std::vector<std::unique_ptr<OutputLayer>> mPendingOutputLayersOrderedByZ; }; return std::make_shared<Output>(compositionEngine, std::forward<Args>(args)...); diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h index 286a20f5af..dd211f1202 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h @@ -64,20 +64,14 @@ public: MOCK_CONST_METHOD1(getOutputLayerForLayer, compositionengine::OutputLayer*(compositionengine::Layer*)); - MOCK_CONST_METHOD2(createOutputLayer, - std::unique_ptr<compositionengine::OutputLayer>( - const std::shared_ptr<compositionengine::Layer>&, - const sp<compositionengine::LayerFE>&)); - MOCK_METHOD2(getOrCreateOutputLayer, - std::unique_ptr<compositionengine::OutputLayer>( - std::shared_ptr<compositionengine::Layer>, - sp<compositionengine::LayerFE>)); - - MOCK_METHOD1(setOutputLayersOrderedByZ, void(OutputLayers&&)); - MOCK_CONST_METHOD0(getOutputLayersOrderedByZ, OutputLayers&()); + MOCK_METHOD0(clearOutputLayers, void()); + MOCK_METHOD2(injectOutputLayerForTest, + compositionengine::OutputLayer*(const std::shared_ptr<compositionengine::Layer>&, + const sp<compositionengine::LayerFE>&)); + MOCK_CONST_METHOD0(getOutputLayerCount, size_t()); + MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t)); MOCK_METHOD1(setReleasedLayers, void(ReleasedLayers&&)); - MOCK_METHOD0(takeReleasedLayers, ReleasedLayers()); MOCK_METHOD2(prepare, void(const compositionengine::CompositionRefreshArgs&, LayerFESet&)); MOCK_METHOD1(present, void(const compositionengine::CompositionRefreshArgs&)); @@ -87,10 +81,9 @@ public: MOCK_METHOD2(collectVisibleLayers, void(const compositionengine::CompositionRefreshArgs&, compositionengine::Output::CoverageState&)); - MOCK_METHOD2(getOutputLayerIfVisible, - std::unique_ptr<compositionengine::OutputLayer>( - std::shared_ptr<compositionengine::Layer>, - compositionengine::Output::CoverageState&)); + MOCK_METHOD2(ensureOutputLayerIfVisible, + void(std::shared_ptr<compositionengine::Layer>, + compositionengine::Output::CoverageState&)); MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&)); MOCK_CONST_METHOD1(updateLayerStateFromFE, void(const CompositionRefreshArgs&)); diff --git a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp index abf73adcbd..295c289ce8 100644 --- a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp +++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp @@ -101,7 +101,7 @@ void CompositionEngine::updateCursorAsync(CompositionRefreshArgs& args) { uniqueVisibleLayers; for (const auto& output : args.outputs) { - for (auto& layer : output->getOutputLayersOrderedByZ()) { + for (auto* layer : output->getOutputLayersOrderedByZ()) { if (layer->isHardwareCursor()) { // Latch the cursor composition state from each front-end layer. layer->getLayerFE().latchCursorCompositionState(layer->getLayer().editFEState()); diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp index 87df85846f..405ad42058 100644 --- a/services/surfaceflinger/CompositionEngine/src/Display.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp @@ -132,7 +132,7 @@ void Display::createRenderSurface(const RenderSurfaceCreationArgs& args) { std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer( const std::shared_ptr<compositionengine::Layer>& layer, const sp<compositionengine::LayerFE>& layerFE) const { - auto result = Output::createOutputLayer(layer, layerFE); + auto result = impl::createOutputLayer(*this, layer, layerFE); if (result && mId) { auto& hwc = getCompositionEngine().getHwComposer(); @@ -167,7 +167,7 @@ void Display::setReleasedLayers(const compositionengine::CompositionRefreshArgs& // Any non-null entries in the current list of layers are layers that are no // longer going to be visible - for (auto& layer : getOutputLayersOrderedByZ()) { + for (auto* layer : getOutputLayersOrderedByZ()) { if (!layer) { continue; } @@ -230,14 +230,14 @@ bool Display::getSkipColorTransform() const { } bool Display::anyLayersRequireClientComposition() const { - const auto& layers = getOutputLayersOrderedByZ(); - return std::any_of(layers.cbegin(), layers.cend(), + const auto layers = getOutputLayersOrderedByZ(); + return std::any_of(layers.begin(), layers.end(), [](const auto& layer) { return layer->requiresClientComposition(); }); } bool Display::allLayersRequireClientComposition() const { - const auto& layers = getOutputLayersOrderedByZ(); - return std::all_of(layers.cbegin(), layers.cend(), + const auto layers = getOutputLayersOrderedByZ(); + return std::all_of(layers.begin(), layers.end(), [](const auto& layer) { return layer->requiresClientComposition(); }); } @@ -246,7 +246,7 @@ void Display::applyChangedTypesToLayers(const ChangedTypes& changedTypes) { return; } - for (auto& layer : getOutputLayersOrderedByZ()) { + for (auto* layer : getOutputLayersOrderedByZ()) { auto hwcLayer = layer->getHwcLayer(); if (!hwcLayer) { continue; @@ -267,7 +267,7 @@ void Display::applyDisplayRequests(const DisplayRequests& displayRequests) { } void Display::applyLayerRequestsToLayers(const LayerRequests& layerRequests) { - for (auto& layer : getOutputLayersOrderedByZ()) { + for (auto* layer : getOutputLayersOrderedByZ()) { layer->prepareForDeviceLayerRequests(); auto hwcLayer = layer->getHwcLayer(); @@ -295,7 +295,7 @@ compositionengine::Output::FrameFences Display::presentAndGetFrameFences() { result.presentFence = hwc.getPresentFence(*mId); // TODO(b/121291683): Change HWComposer call to return entire map - for (const auto& layer : getOutputLayersOrderedByZ()) { + for (const auto* layer : getOutputLayersOrderedByZ()) { auto hwcLayer = layer->getHwcLayer(); if (!hwcLayer) { continue; diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index c511306466..c3e5cfde5a 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -186,8 +186,8 @@ void Output::dumpBase(std::string& out) const { out.append(" No render surface!\n"); } - android::base::StringAppendF(&out, "\n %zu Layers\b", mOutputLayersOrderedByZ.size()); - for (const auto& outputLayer : mOutputLayersOrderedByZ) { + android::base::StringAppendF(&out, "\n %zu Layers\n", getOutputLayerCount()); + for (const auto* outputLayer : getOutputLayersOrderedByZ()) { if (!outputLayer) { continue; } @@ -253,49 +253,32 @@ bool Output::belongsInOutput(const compositionengine::Layer* layer) const { return belongsInOutput(layerFEState.layerStackId, layerFEState.internalOnly); } +std::unique_ptr<compositionengine::OutputLayer> Output::createOutputLayer( + const std::shared_ptr<compositionengine::Layer>& layer, const sp<LayerFE>& layerFE) const { + return impl::createOutputLayer(*this, layer, layerFE); +} + compositionengine::OutputLayer* Output::getOutputLayerForLayer( compositionengine::Layer* layer) const { - for (const auto& outputLayer : mOutputLayersOrderedByZ) { - if (outputLayer && &outputLayer->getLayer() == layer) { - return outputLayer.get(); - } - } - return nullptr; + auto index = findCurrentOutputLayerForLayer(layer); + return index ? getOutputLayerOrderedByZByIndex(*index) : nullptr; } -std::unique_ptr<compositionengine::OutputLayer> Output::takeOutputLayerForLayer( - compositionengine::Layer* layer) { - // Removes the outputLayer from mOutputLayersorderedByZ and transfers ownership to the caller. - for (auto& outputLayer : mOutputLayersOrderedByZ) { +std::optional<size_t> Output::findCurrentOutputLayerForLayer( + compositionengine::Layer* layer) const { + for (size_t i = 0; i < getOutputLayerCount(); i++) { + auto outputLayer = getOutputLayerOrderedByZByIndex(i); if (outputLayer && &outputLayer->getLayer() == layer) { - return std::move(outputLayer); + return i; } } - return nullptr; -} - -std::unique_ptr<compositionengine::OutputLayer> Output::createOutputLayer( - const std::shared_ptr<compositionengine::Layer>& layer, - const sp<compositionengine::LayerFE>& layerFE) const { - return impl::createOutputLayer(*this, layer, layerFE); -} - -void Output::setOutputLayersOrderedByZ(OutputLayers&& layers) { - mOutputLayersOrderedByZ = std::move(layers); -} - -const Output::OutputLayers& Output::getOutputLayersOrderedByZ() const { - return mOutputLayersOrderedByZ; + return std::nullopt; } void Output::setReleasedLayers(Output::ReleasedLayers&& layers) { mReleasedLayers = std::move(layers); } -Output::ReleasedLayers Output::takeReleasedLayers() { - return std::move(mReleasedLayers); -} - void Output::prepare(const compositionengine::CompositionRefreshArgs& refreshArgs, LayerFESet& geomSnapshots) { ATRACE_CALL(); @@ -345,47 +328,34 @@ void Output::rebuildLayerStacks(const compositionengine::CompositionRefreshArgs& void Output::collectVisibleLayers(const compositionengine::CompositionRefreshArgs& refreshArgs, compositionengine::Output::CoverageState& coverage) { - // We build up a list of all layers that are going to be visible in the new - // frame. - compositionengine::Output::OutputLayers newLayersSortedByZ; - // Evaluate the layers from front to back to determine what is visible. This // also incrementally calculates the coverage information for each layer as // well as the entire output. for (auto& layer : reversed(refreshArgs.layers)) { - // Incrementally process the coverage for each layer, obtaining an - // optional outputLayer if the layer is visible. - auto outputLayer = getOutputLayerIfVisible(layer, coverage); - if (outputLayer) { - newLayersSortedByZ.emplace_back(std::move(outputLayer)); - } + // Incrementally process the coverage for each layer + ensureOutputLayerIfVisible(layer, coverage); // TODO(b/121291683): Stop early if the output is completely covered and // no more layers could even be visible underneath the ones on top. } - // Since we walked the layers in reverse order, we need to reverse - // newLayersSortedByZ to get the back-to-front ordered list of layers. - std::reverse(newLayersSortedByZ.begin(), newLayersSortedByZ.end()); + setReleasedLayers(refreshArgs); + + finalizePendingOutputLayers(); // Generate a simple Z-order values to each visible output layer uint32_t zOrder = 0; - for (auto& outputLayer : newLayersSortedByZ) { + for (auto* outputLayer : getOutputLayersOrderedByZ()) { outputLayer->editState().z = zOrder++; } - - setReleasedLayers(refreshArgs); - - mOutputLayersOrderedByZ = std::move(newLayersSortedByZ); } -std::unique_ptr<compositionengine::OutputLayer> Output::getOutputLayerIfVisible( - std::shared_ptr<compositionengine::Layer> layer, - compositionengine::Output::CoverageState& coverage) { +void Output::ensureOutputLayerIfVisible(std::shared_ptr<compositionengine::Layer> layer, + compositionengine::Output::CoverageState& coverage) { // Note: Converts a wp<LayerFE> to a sp<LayerFE> auto layerFE = layer->getLayerFE(); if (layerFE == nullptr) { - return nullptr; + return; } // Ensure we have a snapshot of the basic geometry layer state. Limit the @@ -402,7 +372,7 @@ std::unique_ptr<compositionengine::OutputLayer> Output::getOutputLayerIfVisible( // Only consider the layers on the given layer stack if (!belongsInOutput(layer.get())) { - return nullptr; + return; } /* @@ -436,7 +406,7 @@ std::unique_ptr<compositionengine::OutputLayer> Output::getOutputLayerIfVisible( // handle hidden surfaces by setting the visible region to empty if (CC_UNLIKELY(!layerFEState.isVisible)) { - return nullptr; + return; } const ui::Transform& tr = layerFEState.geomLayerTransform; @@ -447,7 +417,7 @@ std::unique_ptr<compositionengine::OutputLayer> Output::getOutputLayerIfVisible( visibleRegion.set(Rect(tr.transform(layerFEState.geomLayerBounds))); if (visibleRegion.isEmpty()) { - return nullptr; + return; } // Remove the transparent area from the visible region @@ -483,12 +453,14 @@ std::unique_ptr<compositionengine::OutputLayer> Output::getOutputLayerIfVisible( visibleRegion.subtractSelf(coverage.aboveOpaqueLayers); if (visibleRegion.isEmpty()) { - return nullptr; + return; } // Get coverage information for the layer as previously displayed, // also taking over ownership from mOutputLayersorderedByZ. - auto prevOutputLayer = takeOutputLayerForLayer(layer.get()); + auto prevOutputLayerIndex = findCurrentOutputLayerForLayer(layer.get()); + auto prevOutputLayer = + prevOutputLayerIndex ? getOutputLayerOrderedByZByIndex(*prevOutputLayerIndex) : nullptr; // Get coverage information for the layer as previously displayed // TODO(b/121291683): Define kEmptyRegion as a constant in Region.h @@ -540,13 +512,12 @@ std::unique_ptr<compositionengine::OutputLayer> Output::getOutputLayerIfVisible( Region drawRegion(outputState.transform.transform(visibleNonTransparentRegion)); drawRegion.andSelf(outputState.bounds); if (drawRegion.isEmpty()) { - return nullptr; + return; } // The layer is visible. Either reuse the existing outputLayer if we have // one, or create a new one if we do not. - std::unique_ptr<compositionengine::OutputLayer> result = - prevOutputLayer ? std::move(prevOutputLayer) : createOutputLayer(layer, layerFE); + auto result = ensureOutputLayer(prevOutputLayerIndex, layer, layerFE); // Store the layer coverage information into the layer state as some of it // is useful later. @@ -556,8 +527,6 @@ std::unique_ptr<compositionengine::OutputLayer> Output::getOutputLayerIfVisible( outputLayerState.coveredRegion = coveredRegion; outputLayerState.outputSpaceVisibleRegion = outputState.transform.transform( outputLayerState.visibleRegion.intersect(outputState.viewport)); - - return result; } void Output::setReleasedLayers(const compositionengine::CompositionRefreshArgs&) { @@ -565,7 +534,7 @@ void Output::setReleasedLayers(const compositionengine::CompositionRefreshArgs&) } void Output::updateLayerStateFromFE(const CompositionRefreshArgs& args) const { - for (auto& layer : mOutputLayersOrderedByZ) { + for (auto* layer : getOutputLayersOrderedByZ()) { layer->getLayerFE().latchCompositionState(layer->getLayer().editFEState(), args.updatingGeometryThisFrame ? LayerFE::StateSubset::GeometryAndContent @@ -578,7 +547,7 @@ void Output::updateAndWriteCompositionState( ATRACE_CALL(); ALOGV(__FUNCTION__); - for (auto& layer : mOutputLayersOrderedByZ) { + for (auto* layer : getOutputLayersOrderedByZ()) { if (refreshArgs.devOptForceClientComposition) { layer->editState().forceClientComposition = true; } @@ -608,7 +577,7 @@ ui::Dataspace Output::getBestDataspace(ui::Dataspace* outHdrDataSpace, ui::Dataspace bestDataSpace = ui::Dataspace::V0_SRGB; *outHdrDataSpace = ui::Dataspace::UNKNOWN; - for (const auto& layer : mOutputLayersOrderedByZ) { + for (const auto* layer : getOutputLayersOrderedByZ()) { switch (layer->getLayer().getFEState().dataspace) { case ui::Dataspace::V0_SCRGB: case ui::Dataspace::V0_SCRGB_LINEAR: @@ -702,7 +671,7 @@ compositionengine::Output::ColorProfile Output::pickColorProfile( void Output::beginFrame() { auto& outputState = editState(); const bool dirty = !getDirtyRegion(false).isEmpty(); - const bool empty = mOutputLayersOrderedByZ.empty(); + const bool empty = getOutputLayerCount() == 0; const bool wasEmpty = !outputState.lastCompositionHadVisibleLayers; // If nothing has changed (!dirty), don't recompose. @@ -832,11 +801,10 @@ std::optional<base::unique_fd> Output::composeSurfaces(const Region& debugRegion // least one layer has protected content, we need to use a secure back // buffer. if (outputState.isSecure && supportsProtectedContent) { - bool needsProtected = - std::any_of(mOutputLayersOrderedByZ.begin(), mOutputLayersOrderedByZ.end(), - [](auto& layer) { - return layer->getLayer().getFEState().hasProtectedContent; - }); + auto layers = getOutputLayersOrderedByZ(); + bool needsProtected = std::any_of(layers.begin(), layers.end(), [](auto* layer) { + return layer->getLayer().getFEState().hasProtectedContent; + }); if (needsProtected != renderEngine.isProtected()) { renderEngine.useProtectedContext(needsProtected); } @@ -888,7 +856,7 @@ std::vector<renderengine::LayerSettings> Output::generateClientCompositionReques // Used when a layer clears part of the buffer. Region dummyRegion; - for (auto& layer : mOutputLayersOrderedByZ) { + for (auto* layer : getOutputLayersOrderedByZ()) { const auto& layerState = layer->getState(); const auto& layerFEState = layer->getLayer().getFEState(); auto& layerFE = layer->getLayerFE(); @@ -979,7 +947,7 @@ void Output::postFramebuffer() { mRenderSurface->onPresentDisplayCompleted(); - for (auto& layer : mOutputLayersOrderedByZ) { + for (auto* layer : getOutputLayersOrderedByZ()) { // The layer buffer from the previous frame (if any) is released // by HWC only when the release fence from this frame (if any) is // signaled. Always get the release fence from HWC first. @@ -1006,7 +974,7 @@ void Output::postFramebuffer() { } // We've got a list of layers needing fences, that are disjoint with - // mOutputLayersOrderedByZ. The best we can do is to + // OutputLayersOrderedByZ. The best we can do is to // supply them with the present fence. for (auto& weakLayer : mReleasedLayers) { if (auto layer = weakLayer.promote(); layer != nullptr) { diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp index 8401f0827b..4d71d4370a 100644 --- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp @@ -48,17 +48,33 @@ using testing::StrictMock; constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{42}; struct DisplayTest : public testing::Test { + class Display : public impl::Display { + public: + explicit Display(const compositionengine::DisplayCreationArgs& args) + : impl::Display(args) {} + + using impl::Display::injectOutputLayerForTest; + virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0; + }; + + static std::shared_ptr<Display> createDisplay( + const compositionengine::CompositionEngine& compositionEngine, + compositionengine::DisplayCreationArgs&& args) { + return impl::createDisplayTemplated<Display>(compositionEngine, args); + } + DisplayTest() { EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer)); EXPECT_CALL(*mLayer1, getHwcLayer()).WillRepeatedly(Return(&mHWC2Layer1)); EXPECT_CALL(*mLayer2, getHwcLayer()).WillRepeatedly(Return(&mHWC2Layer2)); EXPECT_CALL(*mLayer3, getHwcLayer()).WillRepeatedly(Return(nullptr)); - std::vector<std::unique_ptr<OutputLayer>> layers; - layers.emplace_back(mLayer1); - layers.emplace_back(mLayer2); - layers.emplace_back(mLayer3); - mDisplay->setOutputLayersOrderedByZ(std::move(layers)); + mDisplay->injectOutputLayerForTest( + std::unique_ptr<compositionengine::OutputLayer>(mLayer1)); + mDisplay->injectOutputLayerForTest( + std::unique_ptr<compositionengine::OutputLayer>(mLayer2)); + mDisplay->injectOutputLayerForTest( + std::unique_ptr<compositionengine::OutputLayer>(mLayer3)); } StrictMock<android::mock::HWComposer> mHwComposer; @@ -71,12 +87,11 @@ struct DisplayTest : public testing::Test { mock::OutputLayer* mLayer1 = new StrictMock<mock::OutputLayer>(); mock::OutputLayer* mLayer2 = new StrictMock<mock::OutputLayer>(); mock::OutputLayer* mLayer3 = new StrictMock<mock::OutputLayer>(); - std::shared_ptr<impl::Display> mDisplay = - impl::createDisplay(mCompositionEngine, - DisplayCreationArgsBuilder() - .setDisplayId(DEFAULT_DISPLAY_ID) - .setPowerAdvisor(&mPowerAdvisor) - .build()); + std::shared_ptr<Display> mDisplay = createDisplay(mCompositionEngine, + DisplayCreationArgsBuilder() + .setDisplayId(DEFAULT_DISPLAY_ID) + .setPowerAdvisor(&mPowerAdvisor) + .build()); }; /* @@ -376,7 +391,20 @@ struct DisplayChooseCompositionStrategyTest : public testing::Test { }; // These need implementations though are not expected to be called. + MOCK_CONST_METHOD0(getOutputLayerCount, size_t()); + MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, + compositionengine::OutputLayer*(size_t)); + MOCK_METHOD3(ensureOutputLayer, + compositionengine::OutputLayer*( + std::optional<size_t>, + const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&)); + MOCK_METHOD0(finalizePendingOutputLayers, void()); + MOCK_METHOD0(clearOutputLayers, void()); MOCK_CONST_METHOD1(dumpState, void(std::string&)); + MOCK_METHOD2(injectOutputLayerForTest, + compositionengine::OutputLayer*( + const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&)); + MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>)); const compositionengine::CompositionEngine& mCompositionEngine; impl::OutputCompositionState mState; diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp index 635d77be8a..95ae888767 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp @@ -50,6 +50,17 @@ const mat4 kNonIdentityHalf = mat4() * 0.5; const mat4 kNonIdentityQuarter = mat4() * 0.25; struct OutputTest : public testing::Test { + class Output : public impl::Output { + public: + using impl::Output::injectOutputLayerForTest; + virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0; + }; + + static std::shared_ptr<Output> createOutput( + const compositionengine::CompositionEngine& compositionEngine) { + return impl::createOutputTemplated<Output>(compositionEngine); + } + OutputTest() { mOutput->setDisplayColorProfileForTest( std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile)); @@ -63,7 +74,7 @@ struct OutputTest : public testing::Test { StrictMock<mock::CompositionEngine> mCompositionEngine; mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>(); mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>(); - std::shared_ptr<impl::Output> mOutput = impl::createOutput(mCompositionEngine); + std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine); }; const Rect OutputTest::kDefaultDisplaySize{100, 200}; @@ -449,11 +460,9 @@ TEST_F(OutputTest, getOutputLayerForLayerWorks) { mock::OutputLayer* outputLayer1 = new StrictMock<mock::OutputLayer>(); mock::OutputLayer* outputLayer2 = new StrictMock<mock::OutputLayer>(); - Output::OutputLayers outputLayers; - outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer1)); - outputLayers.emplace_back(nullptr); - outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer2)); - mOutput->setOutputLayersOrderedByZ(std::move(outputLayers)); + mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer1)); + mOutput->injectOutputLayerForTest(nullptr); + mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer2)); StrictMock<mock::Layer> layer; StrictMock<mock::Layer> otherLayer; @@ -488,8 +497,21 @@ struct OutputPrepareFrameTest : public testing::Test { OutputCompositionState& editState() override { return mState; } // These need implementations though are not expected to be called. + MOCK_CONST_METHOD0(getOutputLayerCount, size_t()); + MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, + compositionengine::OutputLayer*(size_t)); + MOCK_METHOD3(ensureOutputLayer, + compositionengine::OutputLayer*( + std::optional<size_t>, + const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&)); + MOCK_METHOD0(finalizePendingOutputLayers, void()); + MOCK_METHOD0(clearOutputLayers, void()); MOCK_CONST_METHOD1(dumpState, void(std::string&)); MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&()); + MOCK_METHOD2(injectOutputLayerForTest, + compositionengine::OutputLayer*( + const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&)); + MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>)); impl::OutputCompositionState mState; }; @@ -566,8 +588,21 @@ struct OutputComposeSurfacesTest : public testing::Test { OutputCompositionState& editState() override { return mState; } // These need implementations though are not expected to be called. + MOCK_CONST_METHOD0(getOutputLayerCount, size_t()); + MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, + compositionengine::OutputLayer*(size_t)); + MOCK_METHOD3(ensureOutputLayer, + compositionengine::OutputLayer*( + std::optional<size_t>, + const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&)); + MOCK_METHOD0(finalizePendingOutputLayers, void()); + MOCK_METHOD0(clearOutputLayers, void()); MOCK_CONST_METHOD1(dumpState, void(std::string&)); MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&()); + MOCK_METHOD2(injectOutputLayerForTest, + compositionengine::OutputLayer*( + const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&)); + MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>)); impl::OutputCompositionState mState; }; @@ -577,11 +612,6 @@ struct OutputComposeSurfacesTest : public testing::Test { std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile)); mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface)); - Output::OutputLayers outputLayers; - outputLayers.emplace_back(std::unique_ptr<OutputLayer>(mOutputLayer1)); - outputLayers.emplace_back(std::unique_ptr<OutputLayer>(mOutputLayer2)); - mOutput.setOutputLayersOrderedByZ(std::move(outputLayers)); - mOutput.editState().frame = kDefaultOutputFrame; mOutput.editState().viewport = kDefaultOutputViewport; mOutput.editState().scissor = kDefaultOutputScissor; @@ -594,6 +624,11 @@ struct OutputComposeSurfacesTest : public testing::Test { mOutput.editState().usesClientComposition = true; mOutput.editState().usesDeviceComposition = false; + EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u)); + EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u)) + .WillRepeatedly(Return(&mOutputLayer1)); + EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u)) + .WillRepeatedly(Return(&mOutputLayer2)); EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine)); EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine)); } @@ -602,8 +637,8 @@ struct OutputComposeSurfacesTest : public testing::Test { StrictMock<renderengine::mock::RenderEngine> mRenderEngine; mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>(); mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>(); - mock::OutputLayer* mOutputLayer1 = new StrictMock<mock::OutputLayer>(); - mock::OutputLayer* mOutputLayer2 = new StrictMock<mock::OutputLayer>(); + StrictMock<mock::OutputLayer> mOutputLayer1; + StrictMock<mock::OutputLayer> mOutputLayer2; StrictMock<OutputPartialMock> mOutput; sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer(); }; @@ -671,8 +706,21 @@ struct GenerateClientCompositionRequestsTest : public testing::Test { OutputCompositionState& editState() override { return mState; } // These need implementations though are not expected to be called. + MOCK_CONST_METHOD0(getOutputLayerCount, size_t()); + MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, + compositionengine::OutputLayer*(size_t)); + MOCK_METHOD3(ensureOutputLayer, + compositionengine::OutputLayer*( + std::optional<size_t>, + const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&)); + MOCK_METHOD0(finalizePendingOutputLayers, void()); + MOCK_METHOD0(clearOutputLayers, void()); MOCK_CONST_METHOD1(dumpState, void(std::string&)); MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&()); + MOCK_METHOD2(injectOutputLayerForTest, + compositionengine::OutputLayer*( + const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&)); + MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>)); impl::OutputCompositionState mState; }; @@ -695,8 +743,8 @@ TEST_F(GenerateClientCompositionRequestsTest, worksForLandscapeModeSplitScreen) // one layer on the left covering the left side of the output, and one layer // on the right covering that side of the output. - mock::OutputLayer* leftOutputLayer = new StrictMock<mock::OutputLayer>(); - mock::OutputLayer* rightOutputLayer = new StrictMock<mock::OutputLayer>(); + StrictMock<mock::OutputLayer> leftOutputLayer; + StrictMock<mock::OutputLayer> rightOutputLayer; StrictMock<mock::Layer> leftLayer; StrictMock<mock::LayerFE> leftLayerFE; @@ -725,26 +773,27 @@ TEST_F(GenerateClientCompositionRequestsTest, worksForLandscapeModeSplitScreen) renderengine::LayerSettings rightLayerRESettings; rightLayerRESettings.source.solidColor = rightLayerColor; - EXPECT_CALL(*leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState)); - EXPECT_CALL(*leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer)); - EXPECT_CALL(*leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE)); - EXPECT_CALL(*leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true)); - EXPECT_CALL(*leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false)); + EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState)); + EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer)); + EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE)); + EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true)); + EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false)); EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState)); EXPECT_CALL(leftLayerFE, prepareClientComposition(_)).WillOnce(Return(leftLayerRESettings)); - EXPECT_CALL(*rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState)); - EXPECT_CALL(*rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer)); - EXPECT_CALL(*rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE)); - EXPECT_CALL(*rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true)); - EXPECT_CALL(*rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false)); + EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState)); + EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer)); + EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE)); + EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true)); + EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false)); EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState)); EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings)); - Output::OutputLayers outputLayers; - outputLayers.emplace_back(std::unique_ptr<OutputLayer>(leftOutputLayer)); - outputLayers.emplace_back(std::unique_ptr<OutputLayer>(rightOutputLayer)); - mOutput.setOutputLayersOrderedByZ(std::move(outputLayers)); + EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u)); + EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u)) + .WillRepeatedly(Return(&leftOutputLayer)); + EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u)) + .WillRepeatedly(Return(&rightOutputLayer)); const Rect kPortraitFrame(0, 0, 1000, 2000); const Rect kPortraitViewport(0, 0, 2000, 1000); @@ -773,7 +822,7 @@ TEST_F(GenerateClientCompositionRequestsTest, ignoresLayersThatDoNotIntersectWit // Layers whose visible region does not intersect with the viewport will be // skipped when generating client composition request state. - mock::OutputLayer* outputLayer = new StrictMock<mock::OutputLayer>(); + StrictMock<mock::OutputLayer> outputLayer; StrictMock<mock::Layer> layer; StrictMock<mock::LayerFE> layerFE; @@ -784,17 +833,16 @@ TEST_F(GenerateClientCompositionRequestsTest, ignoresLayersThatDoNotIntersectWit LayerFECompositionState layerFEState; layerFEState.isOpaque = true; - EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState)); - EXPECT_CALL(*outputLayer, getLayer()).WillRepeatedly(ReturnRef(layer)); - EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE)); - EXPECT_CALL(*outputLayer, requiresClientComposition()).WillRepeatedly(Return(true)); - EXPECT_CALL(*outputLayer, needsFiltering()).WillRepeatedly(Return(false)); + EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState)); + EXPECT_CALL(outputLayer, getLayer()).WillRepeatedly(ReturnRef(layer)); + EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE)); + EXPECT_CALL(outputLayer, requiresClientComposition()).WillRepeatedly(Return(true)); + EXPECT_CALL(outputLayer, needsFiltering()).WillRepeatedly(Return(false)); EXPECT_CALL(layer, getFEState()).WillRepeatedly(ReturnRef(layerFEState)); EXPECT_CALL(layerFE, prepareClientComposition(_)).Times(0); - Output::OutputLayers outputLayers; - outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer)); - mOutput.setOutputLayersOrderedByZ(std::move(outputLayers)); + EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u)); + EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u)).WillRepeatedly(Return(&outputLayer)); const Rect kPortraitFrame(0, 0, 1000, 2000); const Rect kPortraitViewport(0, 0, 2000, 1000); @@ -824,8 +872,8 @@ TEST_F(GenerateClientCompositionRequestsTest, clearsDeviceLayesAfterFirst) { // set to do so. The first layer is skipped as the frame buffer is already // expected to be clear. - mock::OutputLayer* leftOutputLayer = new StrictMock<mock::OutputLayer>(); - mock::OutputLayer* rightOutputLayer = new StrictMock<mock::OutputLayer>(); + StrictMock<mock::OutputLayer> leftOutputLayer; + StrictMock<mock::OutputLayer> rightOutputLayer; StrictMock<mock::Layer> leftLayer; StrictMock<mock::LayerFE> leftLayerFE; @@ -851,25 +899,26 @@ TEST_F(GenerateClientCompositionRequestsTest, clearsDeviceLayesAfterFirst) { rightLayerRESettings.geometry.boundaries = FloatRect{456, 0, 0, 0}; rightLayerRESettings.source.solidColor = rightLayerColor; - EXPECT_CALL(*leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState)); - EXPECT_CALL(*leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer)); - EXPECT_CALL(*leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE)); - EXPECT_CALL(*leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); - EXPECT_CALL(*leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false)); + EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState)); + EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer)); + EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE)); + EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); + EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false)); EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState)); - EXPECT_CALL(*rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState)); - EXPECT_CALL(*rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer)); - EXPECT_CALL(*rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE)); - EXPECT_CALL(*rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); - EXPECT_CALL(*rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false)); + EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState)); + EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer)); + EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE)); + EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); + EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false)); EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState)); EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings)); - Output::OutputLayers outputLayers; - outputLayers.emplace_back(std::unique_ptr<OutputLayer>(leftOutputLayer)); - outputLayers.emplace_back(std::unique_ptr<OutputLayer>(rightOutputLayer)); - mOutput.setOutputLayersOrderedByZ(std::move(outputLayers)); + EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u)); + EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u)) + .WillRepeatedly(Return(&leftOutputLayer)); + EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u)) + .WillRepeatedly(Return(&rightOutputLayer)); const Rect kPortraitFrame(0, 0, 1000, 2000); const Rect kPortraitViewport(0, 0, 2000, 1000); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a9632ec806..f56e6793fc 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1509,8 +1509,7 @@ void SurfaceFlinger::updateVrFlinger() { // any HWC layers are destroyed through that interface before it becomes // invalid. for (const auto& [token, displayDevice] : mDisplays) { - displayDevice->getCompositionDisplay()->setOutputLayersOrderedByZ( - compositionengine::Output::OutputLayers()); + displayDevice->getCompositionDisplay()->clearOutputLayers(); } // This DisplayDevice will no longer be relevant once resetDisplayState() is diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 20dfed65e2..539e0f449d 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -812,14 +812,10 @@ struct BaseLayerVariant { EXPECT_CALL(*test->mComposer, createLayer(HWC_DISPLAY, _)) .WillOnce(DoAll(SetArgPointee<1>(HWC_LAYER), Return(Error::NONE))); - std::vector<std::unique_ptr<compositionengine::OutputLayer>> outputLayers; - outputLayers.emplace_back(test->mDisplay->getCompositionDisplay() - ->createOutputLayer(layer->getCompositionLayer(), layer)); - - outputLayers.back()->editState().visibleRegion = Region(Rect(0, 0, 100, 100)); - outputLayers.back()->editState().outputSpaceVisibleRegion = Region(Rect(0, 0, 100, 100)); - - test->mDisplay->getCompositionDisplay()->setOutputLayersOrderedByZ(std::move(outputLayers)); + auto outputLayer = test->mDisplay->getCompositionDisplay() + ->injectOutputLayerForTest(layer->getCompositionLayer(), layer); + outputLayer->editState().visibleRegion = Region(Rect(0, 0, 100, 100)); + outputLayer->editState().outputSpaceVisibleRegion = Region(Rect(0, 0, 100, 100)); Mock::VerifyAndClear(test->mComposer); @@ -830,8 +826,7 @@ struct BaseLayerVariant { EXPECT_CALL(*test->mComposer, destroyLayer(HWC_DISPLAY, HWC_LAYER)) .WillOnce(Return(Error::NONE)); - test->mDisplay->getCompositionDisplay()->setOutputLayersOrderedByZ( - std::vector<std::unique_ptr<compositionengine::OutputLayer>>()); + test->mDisplay->getCompositionDisplay()->clearOutputLayers(); test->mFlinger.mutableDrawingState().layersSortedByZ.clear(); } }; |