summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Lloyd Pique <lpique@google.com> 2019-04-17 12:48:32 -0700
committer Lloyd Pique <lpique@google.com> 2019-09-25 13:09:49 -0700
commit01c77c1a2d05e08132b4818feb0ff9e3e09a3b42 (patch)
tree0067bfe2fea4999d20144ee2dd0fd2edb979a2af
parenta38ea7e70d047eb5557e3b3425fd45bb4ca5c6a9 (diff)
CE: Move knowledge of the OutputLayers out of Output
This separates knowledge of the type and management of OutputLayers from the implementation of the Output class. 1) getOutputLayersOrderedByZ() is now a non-virtual function which returns a helper object for iterating over all the layers in the Output, with only minor code changes to the callers. Internally the helper object uses a pair of virtual functions to get the count and access a layer by index. The old interface fixed both the type of the layer and the type of container it was stored in, which was problematic. 2) When rebuilding the layer stack, the implementation now uses additional abstract interface functions that allow the layer stack to be maniupluated without the caller having to own even temporarily instances of the OutputLayer type. 3) The Output interface has been cleaned up to remove functions that were no longer needed in the public interface, and to introduce a few others such as injectOutputLayerForTest() and clearOutputLayers() for performing special layer manipulations. Test: atest libsurfaceflinger_unittest libcompositionengine_test Test: go/wm-smoke Bug: 121291683 Change-Id: I636cfaea7254c7e164837ef8b441932f364808f3
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h96
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h6
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h84
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h25
-rw-r--r--services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp2
-rw-r--r--services/surfaceflinger/CompositionEngine/src/Display.cpp18
-rw-r--r--services/surfaceflinger/CompositionEngine/src/Output.cpp120
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp50
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp157
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp3
-rw-r--r--services/surfaceflinger/tests/unittests/CompositionTest.cpp15
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();
}
};