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 <compositionengine/impl/planner/Planner.h>
24 #include <renderengine/DisplaySettings.h>
25 #include <renderengine/LayerSettings.h>
26 #include <memory>
27 #include <utility>
28 #include <vector>
29
30 namespace android::compositionengine::impl {
31
32 // The implementation class contains the common implementation, but does not
33 // actually contain the final output state.
34 class Output : public virtual compositionengine::Output {
35 public:
36 Output() = default;
37 ~Output() override;
38
39 // compositionengine::Output overrides
40 bool isValid() const override;
41 std::optional<DisplayId> getDisplayId() const override;
42 void setCompositionEnabled(bool) override;
43 void setLayerCachingEnabled(bool) override;
44 void setLayerCachingTexturePoolEnabled(bool) override;
45 void setProjection(ui::Rotation orientation, const Rect& layerStackSpaceRect,
46 const Rect& orientedDisplaySpaceRect) override;
47 void setDisplaySize(const ui::Size&) override;
48 void setLayerStackFilter(uint32_t layerStackId, bool isInternal) override;
49 ui::Transform::RotationFlags getTransformHint() const override;
50
51 void setColorTransform(const compositionengine::CompositionRefreshArgs&) override;
52 void setColorProfile(const ColorProfile&) override;
53 void setDisplayBrightness(float sdrWhitePointNits, float displayBrightnessNits) override;
54
55 void dump(std::string&) const override;
56 void dumpPlannerInfo(const Vector<String16>& args, std::string&) const override;
57
58 const std::string& getName() const override;
59 void setName(const std::string&) override;
60
61 compositionengine::DisplayColorProfile* getDisplayColorProfile() const override;
62 void setDisplayColorProfile(std::unique_ptr<compositionengine::DisplayColorProfile>) override;
63
64 compositionengine::RenderSurface* getRenderSurface() const override;
65 void setRenderSurface(std::unique_ptr<compositionengine::RenderSurface>) override;
66
67 Region getDirtyRegion(bool repaintEverything) const override;
68 bool belongsInOutput(std::optional<uint32_t>, bool) const override;
69 bool belongsInOutput(const sp<LayerFE>&) const override;
70
71 compositionengine::OutputLayer* getOutputLayerForLayer(const sp<LayerFE>&) const override;
72
73 void setReleasedLayers(ReleasedLayers&&) override;
74
75 void prepare(const CompositionRefreshArgs&, LayerFESet&) override;
76 void present(const CompositionRefreshArgs&) override;
77
78 void rebuildLayerStacks(const CompositionRefreshArgs&, LayerFESet&) override;
79 void collectVisibleLayers(const CompositionRefreshArgs&,
80 compositionengine::Output::CoverageState&) override;
81 void ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>&,
82 compositionengine::Output::CoverageState&) override;
83 void setReleasedLayers(const compositionengine::CompositionRefreshArgs&) override;
84
85 void updateLayerStateFromFE(const CompositionRefreshArgs&) const override;
86 void updateCompositionState(const compositionengine::CompositionRefreshArgs&) override;
87 void planComposition() override;
88 void writeCompositionState(const compositionengine::CompositionRefreshArgs&) override;
89 void updateColorProfile(const compositionengine::CompositionRefreshArgs&) override;
90 void beginFrame() override;
91 void prepareFrame() override;
92 void devOptRepaintFlash(const CompositionRefreshArgs&) override;
93 void finishFrame(const CompositionRefreshArgs&) override;
94 std::optional<base::unique_fd> composeSurfaces(
95 const Region&, const compositionengine::CompositionRefreshArgs& refreshArgs) override;
96 void postFramebuffer() override;
97 void renderCachedSets(const CompositionRefreshArgs&) override;
98 void cacheClientCompositionRequests(uint32_t) override;
99
100 // Testing
101 const ReleasedLayers& getReleasedLayersForTest() const;
102 void setDisplayColorProfileForTest(std::unique_ptr<compositionengine::DisplayColorProfile>);
103 void setRenderSurfaceForTest(std::unique_ptr<compositionengine::RenderSurface>);
plannerEnabled()104 bool plannerEnabled() const { return mPlanner != nullptr; }
105
106 protected:
107 std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(const sp<LayerFE>&) const;
108 std::optional<size_t> findCurrentOutputLayerForLayer(
109 const sp<compositionengine::LayerFE>&) const;
110 void chooseCompositionStrategy() override;
111 bool getSkipColorTransform() const override;
112 compositionengine::Output::FrameFences presentAndGetFrameFences() override;
113 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
114 bool supportsProtectedContent, Region& clearRegion,
115 ui::Dataspace outputDataspace) override;
116 void appendRegionFlashRequests(const Region&, std::vector<LayerFE::LayerSettings>&) override;
117 void setExpensiveRenderingExpected(bool enabled) override;
118 void dumpBase(std::string&) const;
119
120 // Implemented by the final implementation for the final state it uses.
121 virtual compositionengine::OutputLayer* ensureOutputLayer(std::optional<size_t>,
122 const sp<LayerFE>&) = 0;
123 virtual compositionengine::OutputLayer* injectOutputLayerForTest(const sp<LayerFE>&) = 0;
124 virtual void finalizePendingOutputLayers() = 0;
125 virtual const compositionengine::CompositionEngine& getCompositionEngine() const = 0;
126 virtual void dumpState(std::string& out) const = 0;
127
128 private:
129 void dirtyEntireOutput();
130 compositionengine::OutputLayer* findLayerRequestingBackgroundComposition() const;
131 ui::Dataspace getBestDataspace(ui::Dataspace*, bool*) const;
132 compositionengine::Output::ColorProfile pickColorProfile(
133 const compositionengine::CompositionRefreshArgs&) const;
134
135 std::string mName;
136
137 std::unique_ptr<compositionengine::DisplayColorProfile> mDisplayColorProfile;
138 std::unique_ptr<compositionengine::RenderSurface> mRenderSurface;
139
140 ReleasedLayers mReleasedLayers;
141 OutputLayer* mLayerRequestingBackgroundBlur = nullptr;
142 std::unique_ptr<ClientCompositionRequestCache> mClientCompositionRequestCache;
143 std::unique_ptr<planner::Planner> mPlanner;
144 };
145
146 // This template factory function standardizes the implementation details of the
147 // final class using the types actually required by the implementation. This is
148 // not possible to do in the base class as those types may not even be visible
149 // to the base code.
150 template <typename BaseOutput, typename CompositionEngine, typename... Args>
createOutputTemplated(const CompositionEngine & compositionEngine,Args...args)151 std::shared_ptr<BaseOutput> createOutputTemplated(const CompositionEngine& compositionEngine,
152 Args... args) {
153 class Output final : public BaseOutput {
154 public:
155 // Clang incorrectly complains that these are unused.
156 #pragma clang diagnostic push
157 #pragma clang diagnostic ignored "-Wunused-local-typedef"
158
159 using OutputCompositionState = std::remove_const_t<
160 std::remove_reference_t<decltype(std::declval<BaseOutput>().getState())>>;
161 using OutputLayer = std::remove_pointer_t<decltype(
162 std::declval<BaseOutput>().getOutputLayerOrderedByZByIndex(0))>;
163
164 #pragma clang diagnostic pop
165
166 explicit Output(const CompositionEngine& compositionEngine, Args... args)
167 : BaseOutput(std::forward<Args>(args)...), mCompositionEngine(compositionEngine) {}
168 ~Output() override = default;
169
170 private:
171 // compositionengine::Output overrides
172 const OutputCompositionState& getState() const override { return mState; }
173
174 OutputCompositionState& editState() override { return mState; }
175
176 size_t getOutputLayerCount() const override {
177 return mCurrentOutputLayersOrderedByZ.size();
178 }
179
180 OutputLayer* getOutputLayerOrderedByZByIndex(size_t index) const override {
181 if (index >= mCurrentOutputLayersOrderedByZ.size()) {
182 return nullptr;
183 }
184 return mCurrentOutputLayersOrderedByZ[index].get();
185 }
186
187 // compositionengine::impl::Output overrides
188 const CompositionEngine& getCompositionEngine() const override {
189 return mCompositionEngine;
190 };
191
192 OutputLayer* ensureOutputLayer(std::optional<size_t> prevIndex,
193 const sp<LayerFE>& layerFE) {
194 auto outputLayer = (prevIndex && *prevIndex <= mCurrentOutputLayersOrderedByZ.size())
195 ? std::move(mCurrentOutputLayersOrderedByZ[*prevIndex])
196 : BaseOutput::createOutputLayer(layerFE);
197 auto result = outputLayer.get();
198 mPendingOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
199 return result;
200 }
201
202 void finalizePendingOutputLayers() override {
203 // The pending layers are added in reverse order. Reverse them to
204 // get the back-to-front ordered list of layers.
205 std::reverse(mPendingOutputLayersOrderedByZ.begin(),
206 mPendingOutputLayersOrderedByZ.end());
207
208 mCurrentOutputLayersOrderedByZ = std::move(mPendingOutputLayersOrderedByZ);
209 }
210
211 void dumpState(std::string& out) const override { mState.dump(out); }
212
213 OutputLayer* injectOutputLayerForTest(const sp<LayerFE>& layerFE) override {
214 auto outputLayer = BaseOutput::createOutputLayer(layerFE);
215 auto result = outputLayer.get();
216 mCurrentOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
217 return result;
218 }
219
220 // Note: This is declared as a private virtual non-override so it can be
221 // an override implementation in the unit tests, but otherwise is not an
222 // accessible override for the normal implementation.
223 virtual void injectOutputLayerForTest(std::unique_ptr<OutputLayer> outputLayer) {
224 mCurrentOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
225 }
226
227 void clearOutputLayers() override {
228 mCurrentOutputLayersOrderedByZ.clear();
229 mPendingOutputLayersOrderedByZ.clear();
230 }
231
232 const CompositionEngine& mCompositionEngine;
233 OutputCompositionState mState;
234 std::vector<std::unique_ptr<OutputLayer>> mCurrentOutputLayersOrderedByZ;
235 std::vector<std::unique_ptr<OutputLayer>> mPendingOutputLayersOrderedByZ;
236 };
237
238 return std::make_shared<Output>(compositionEngine, std::forward<Args>(args)...);
239 }
240
241 std::shared_ptr<Output> createOutput(const compositionengine::CompositionEngine&);
242
243 } // namespace android::compositionengine::impl
244