1 /*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #pragma once
18
19 #include <compositionengine/CompositionEngine.h>
20 #include <compositionengine/Output.h>
21 #include <compositionengine/impl/ClientCompositionRequestCache.h>
22 #include <compositionengine/impl/OutputCompositionState.h>
23 #include <renderengine/DisplaySettings.h>
24 #include <renderengine/LayerSettings.h>
25 #include <memory>
26 #include <utility>
27 #include <vector>
28
29 namespace android::compositionengine::impl {
30
31 // The implementation class contains the common implementation, but does not
32 // actually contain the final output state.
33 class Output : public virtual compositionengine::Output {
34 public:
35 ~Output() override;
36
37 // compositionengine::Output overrides
38 bool isValid() const override;
39 std::optional<DisplayId> getDisplayId() const override;
40 void setCompositionEnabled(bool) override;
41 void setProjection(const ui::Transform&, uint32_t orientation, const Rect& frame,
42 const Rect& viewport, const Rect& sourceClip, const Rect& destinationClip,
43 bool needsFiltering) override;
44 void setBounds(const ui::Size&) override;
45 void setLayerStackFilter(uint32_t layerStackId, bool isInternal) override;
46
47 void setColorTransform(const compositionengine::CompositionRefreshArgs&) override;
48 void setColorProfile(const ColorProfile&) override;
49
50 void dump(std::string&) const override;
51
52 const std::string& getName() const override;
53 void setName(const std::string&) override;
54
55 compositionengine::DisplayColorProfile* getDisplayColorProfile() const override;
56 void setDisplayColorProfile(std::unique_ptr<compositionengine::DisplayColorProfile>) override;
57
58 compositionengine::RenderSurface* getRenderSurface() const override;
59 void setRenderSurface(std::unique_ptr<compositionengine::RenderSurface>) override;
60
61 Region getDirtyRegion(bool repaintEverything) const override;
62 bool belongsInOutput(std::optional<uint32_t>, bool) const override;
63 bool belongsInOutput(const sp<LayerFE>&) const override;
64
65 compositionengine::OutputLayer* getOutputLayerForLayer(const sp<LayerFE>&) const override;
66
67 void setReleasedLayers(ReleasedLayers&&) override;
68
69 void prepare(const CompositionRefreshArgs&, LayerFESet&) override;
70 void present(const CompositionRefreshArgs&) override;
71
72 void rebuildLayerStacks(const CompositionRefreshArgs&, LayerFESet&) override;
73 void collectVisibleLayers(const CompositionRefreshArgs&,
74 compositionengine::Output::CoverageState&) override;
75 void ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>&,
76 compositionengine::Output::CoverageState&) override;
77 void setReleasedLayers(const compositionengine::CompositionRefreshArgs&) override;
78
79 void updateLayerStateFromFE(const CompositionRefreshArgs&) const override;
80 void updateAndWriteCompositionState(const compositionengine::CompositionRefreshArgs&) override;
81 void updateColorProfile(const compositionengine::CompositionRefreshArgs&) override;
82 void beginFrame() override;
83 void prepareFrame() override;
84 void devOptRepaintFlash(const CompositionRefreshArgs&) override;
85 void finishFrame(const CompositionRefreshArgs&) override;
86 std::optional<base::unique_fd> composeSurfaces(
87 const Region&, const compositionengine::CompositionRefreshArgs& refreshArgs) override;
88 void postFramebuffer() override;
89 void cacheClientCompositionRequests(uint32_t) override;
90
91 // Testing
92 const ReleasedLayers& getReleasedLayersForTest() const;
93 void setDisplayColorProfileForTest(std::unique_ptr<compositionengine::DisplayColorProfile>);
94 void setRenderSurfaceForTest(std::unique_ptr<compositionengine::RenderSurface>);
95
96 protected:
97 std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(const sp<LayerFE>&) const;
98 std::optional<size_t> findCurrentOutputLayerForLayer(
99 const sp<compositionengine::LayerFE>&) const;
100 void chooseCompositionStrategy() override;
101 bool getSkipColorTransform() const override;
102 compositionengine::Output::FrameFences presentAndGetFrameFences() override;
103 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
104 bool supportsProtectedContent, Region& clearRegion,
105 ui::Dataspace outputDataspace) override;
106 void appendRegionFlashRequests(const Region&, std::vector<LayerFE::LayerSettings>&) override;
107 void setExpensiveRenderingExpected(bool enabled) override;
108 void dumpBase(std::string&) const;
109
110 // Implemented by the final implementation for the final state it uses.
111 virtual compositionengine::OutputLayer* ensureOutputLayer(std::optional<size_t>,
112 const sp<LayerFE>&) = 0;
113 virtual compositionengine::OutputLayer* injectOutputLayerForTest(const sp<LayerFE>&) = 0;
114 virtual void finalizePendingOutputLayers() = 0;
115 virtual const compositionengine::CompositionEngine& getCompositionEngine() const = 0;
116 virtual void dumpState(std::string& out) const = 0;
117
118 private:
119 void dirtyEntireOutput();
120 compositionengine::OutputLayer* findLayerRequestingBackgroundComposition() const;
121 ui::Dataspace getBestDataspace(ui::Dataspace*, bool*) const;
122 compositionengine::Output::ColorProfile pickColorProfile(
123 const compositionengine::CompositionRefreshArgs&) const;
124
125 std::string mName;
126
127 std::unique_ptr<compositionengine::DisplayColorProfile> mDisplayColorProfile;
128 std::unique_ptr<compositionengine::RenderSurface> mRenderSurface;
129
130 ReleasedLayers mReleasedLayers;
131 OutputLayer* mLayerRequestingBackgroundBlur = nullptr;
132 std::unique_ptr<ClientCompositionRequestCache> mClientCompositionRequestCache;
133 };
134
135 // This template factory function standardizes the implementation details of the
136 // final class using the types actually required by the implementation. This is
137 // not possible to do in the base class as those types may not even be visible
138 // to the base code.
139 template <typename BaseOutput, typename CompositionEngine, typename... Args>
createOutputTemplated(const CompositionEngine & compositionEngine,Args...args)140 std::shared_ptr<BaseOutput> createOutputTemplated(const CompositionEngine& compositionEngine,
141 Args... args) {
142 class Output final : public BaseOutput {
143 public:
144 // Clang incorrectly complains that these are unused.
145 #pragma clang diagnostic push
146 #pragma clang diagnostic ignored "-Wunused-local-typedef"
147
148 using OutputCompositionState = std::remove_const_t<
149 std::remove_reference_t<decltype(std::declval<BaseOutput>().getState())>>;
150 using OutputLayer = std::remove_pointer_t<decltype(
151 std::declval<BaseOutput>().getOutputLayerOrderedByZByIndex(0))>;
152
153 #pragma clang diagnostic pop
154
155 explicit Output(const CompositionEngine& compositionEngine, Args... args)
156 : BaseOutput(std::forward<Args>(args)...), mCompositionEngine(compositionEngine) {}
157 ~Output() override = default;
158
159 private:
160 // compositionengine::Output overrides
161 const OutputCompositionState& getState() const override { return mState; }
162
163 OutputCompositionState& editState() override { return mState; }
164
165 size_t getOutputLayerCount() const override {
166 return mCurrentOutputLayersOrderedByZ.size();
167 }
168
169 OutputLayer* getOutputLayerOrderedByZByIndex(size_t index) const override {
170 if (index >= mCurrentOutputLayersOrderedByZ.size()) {
171 return nullptr;
172 }
173 return mCurrentOutputLayersOrderedByZ[index].get();
174 }
175
176 // compositionengine::impl::Output overrides
177 const CompositionEngine& getCompositionEngine() const override {
178 return mCompositionEngine;
179 };
180
181 OutputLayer* ensureOutputLayer(std::optional<size_t> prevIndex,
182 const sp<LayerFE>& layerFE) {
183 auto outputLayer = (prevIndex && *prevIndex <= mCurrentOutputLayersOrderedByZ.size())
184 ? std::move(mCurrentOutputLayersOrderedByZ[*prevIndex])
185 : BaseOutput::createOutputLayer(layerFE);
186 auto result = outputLayer.get();
187 mPendingOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
188 return result;
189 }
190
191 void finalizePendingOutputLayers() override {
192 // The pending layers are added in reverse order. Reverse them to
193 // get the back-to-front ordered list of layers.
194 std::reverse(mPendingOutputLayersOrderedByZ.begin(),
195 mPendingOutputLayersOrderedByZ.end());
196
197 mCurrentOutputLayersOrderedByZ = std::move(mPendingOutputLayersOrderedByZ);
198 }
199
200 void dumpState(std::string& out) const override { mState.dump(out); }
201
202 OutputLayer* injectOutputLayerForTest(const sp<LayerFE>& layerFE) override {
203 auto outputLayer = BaseOutput::createOutputLayer(layerFE);
204 auto result = outputLayer.get();
205 mCurrentOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
206 return result;
207 }
208
209 // Note: This is declared as a private virtual non-override so it can be
210 // an override implementation in the unit tests, but otherwise is not an
211 // accessible override for the normal implementation.
212 virtual void injectOutputLayerForTest(std::unique_ptr<OutputLayer> outputLayer) {
213 mCurrentOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
214 }
215
216 void clearOutputLayers() override {
217 mCurrentOutputLayersOrderedByZ.clear();
218 mPendingOutputLayersOrderedByZ.clear();
219 }
220
221 const CompositionEngine& mCompositionEngine;
222 OutputCompositionState mState;
223 std::vector<std::unique_ptr<OutputLayer>> mCurrentOutputLayersOrderedByZ;
224 std::vector<std::unique_ptr<OutputLayer>> mPendingOutputLayersOrderedByZ;
225 };
226
227 return std::make_shared<Output>(compositionEngine, std::forward<Args>(args)...);
228 }
229
230 std::shared_ptr<Output> createOutput(const compositionengine::CompositionEngine&);
231
232 } // namespace android::compositionengine::impl
233