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