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