summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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();
}
};