• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 #ifndef ANDROID_SF_HWCOMPOSER_H
18 #define ANDROID_SF_HWCOMPOSER_H
19 
20 #include <cstdint>
21 #include <memory>
22 #include <mutex>
23 #include <optional>
24 #include <unordered_map>
25 #include <unordered_set>
26 #include <vector>
27 
28 #include <android-base/thread_annotations.h>
29 #include <ui/Fence.h>
30 #include <ui/GraphicTypes.h>
31 #include <utils/StrongPointer.h>
32 #include <utils/Timers.h>
33 
34 #include "DisplayIdentification.h"
35 #include "HWC2.h"
36 
37 namespace android {
38 
39 struct DisplayedFrameStats;
40 class GraphicBuffer;
41 class TestableSurfaceFlinger;
42 struct CompositionInfo;
43 
44 namespace Hwc2 {
45 class Composer;
46 } // namespace Hwc2
47 
48 namespace compositionengine {
49 class Output;
50 } // namespace compositionengine
51 
52 class HWComposer {
53 public:
54     virtual ~HWComposer();
55 
56     virtual void registerCallback(HWC2::ComposerCallback* callback, int32_t sequenceId) = 0;
57 
58     virtual bool getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
59                                               DisplayIdentificationData* outData) const = 0;
60 
61     virtual bool hasCapability(HWC2::Capability capability) const = 0;
62     virtual bool hasDisplayCapability(const std::optional<DisplayId>& displayId,
63                                       HWC2::DisplayCapability capability) const = 0;
64 
65     // Attempts to allocate a virtual display and returns its ID if created on the HWC device.
66     virtual std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
67                                                             ui::PixelFormat* format) = 0;
68 
69     // Attempts to create a new layer on this display
70     virtual HWC2::Layer* createLayer(DisplayId displayId) = 0;
71     // Destroy a previously created layer
72     virtual void destroyLayer(DisplayId displayId, HWC2::Layer* layer) = 0;
73 
74     // Asks the HAL what it can do
75     virtual status_t prepare(DisplayId displayId, const compositionengine::Output&) = 0;
76 
77     virtual status_t setClientTarget(DisplayId displayId, uint32_t slot,
78                                      const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
79                                      ui::Dataspace dataspace) = 0;
80 
81     // Present layers to the display and read releaseFences.
82     virtual status_t presentAndGetReleaseFences(DisplayId displayId) = 0;
83 
84     // set power mode
85     virtual status_t setPowerMode(DisplayId displayId, int mode) = 0;
86 
87     // set active config
88     virtual status_t setActiveConfig(DisplayId displayId, size_t configId) = 0;
89 
90     // Sets a color transform to be applied to the result of composition
91     virtual status_t setColorTransform(DisplayId displayId, const mat4& transform) = 0;
92 
93     // reset state when an external, non-virtual display is disconnected
94     virtual void disconnectDisplay(DisplayId displayId) = 0;
95 
96     // does this display have layers handled by HWC
97     virtual bool hasDeviceComposition(const std::optional<DisplayId>& displayId) const = 0;
98 
99     // does this display have pending request to flip client target
100     virtual bool hasFlipClientTargetRequest(const std::optional<DisplayId>& displayId) const = 0;
101 
102     // does this display have layers handled by GLES
103     virtual bool hasClientComposition(const std::optional<DisplayId>& displayId) const = 0;
104 
105     // get the present fence received from the last call to present.
106     virtual sp<Fence> getPresentFence(DisplayId displayId) const = 0;
107 
108     // Get last release fence for the given layer
109     virtual sp<Fence> getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const = 0;
110 
111     // Set the output buffer and acquire fence for a virtual display.
112     // Returns INVALID_OPERATION if displayId is not a virtual display.
113     virtual status_t setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence,
114                                      const sp<GraphicBuffer>& buffer) = 0;
115 
116     // After SurfaceFlinger has retrieved the release fences for all the frames,
117     // it can call this to clear the shared pointers in the release fence map
118     virtual void clearReleaseFences(DisplayId displayId) = 0;
119 
120     // Fetches the HDR capabilities of the given display
121     virtual status_t getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities) = 0;
122 
123     virtual int32_t getSupportedPerFrameMetadata(DisplayId displayId) const = 0;
124 
125     // Returns the available RenderIntent of the given display.
126     virtual std::vector<ui::RenderIntent> getRenderIntents(DisplayId displayId,
127                                                            ui::ColorMode colorMode) const = 0;
128 
129     virtual mat4 getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace) = 0;
130 
131     // Returns the attributes of the color sampling engine.
132     virtual status_t getDisplayedContentSamplingAttributes(DisplayId displayId,
133                                                            ui::PixelFormat* outFormat,
134                                                            ui::Dataspace* outDataspace,
135                                                            uint8_t* outComponentMask) = 0;
136     virtual status_t setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
137                                                       uint8_t componentMask,
138                                                       uint64_t maxFrames) = 0;
139     virtual status_t getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames,
140                                                uint64_t timestamp,
141                                                DisplayedFrameStats* outStats) = 0;
142 
143     // Sets the brightness of a display.
144     virtual status_t setDisplayBrightness(DisplayId displayId, float brightness) = 0;
145 
146     // Events handling ---------------------------------------------------------
147 
148     // Returns stable display ID (and display name on connection of new or previously disconnected
149     // display), or std::nullopt if hotplug event was ignored.
150     virtual std::optional<DisplayIdentificationInfo> onHotplug(hwc2_display_t hwcDisplayId,
151                                                                HWC2::Connection connection) = 0;
152 
153     virtual bool onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp) = 0;
154     virtual void setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled) = 0;
155 
156     virtual nsecs_t getRefreshTimestamp(DisplayId displayId) const = 0;
157     virtual bool isConnected(DisplayId displayId) const = 0;
158 
159     // Non-const because it can update configMap inside of mDisplayData
160     virtual std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(
161             DisplayId displayId) const = 0;
162 
163     virtual std::shared_ptr<const HWC2::Display::Config> getActiveConfig(
164             DisplayId displayId) const = 0;
165     virtual int getActiveConfigIndex(DisplayId displayId) const = 0;
166 
167     virtual std::vector<ui::ColorMode> getColorModes(DisplayId displayId) const = 0;
168 
169     virtual status_t setActiveColorMode(DisplayId displayId, ui::ColorMode mode,
170                                         ui::RenderIntent renderIntent) = 0;
171 
172     virtual bool isUsingVrComposer() const = 0;
173 
174     // for debugging ----------------------------------------------------------
175     virtual void dump(std::string& out) const = 0;
176 
177     virtual Hwc2::Composer* getComposer() const = 0;
178 
179     // TODO(b/74619554): Remove special cases for internal/external display.
180     virtual std::optional<hwc2_display_t> getInternalHwcDisplayId() const = 0;
181     virtual std::optional<hwc2_display_t> getExternalHwcDisplayId() const = 0;
182 
183     virtual std::optional<DisplayId> toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const = 0;
184     virtual std::optional<hwc2_display_t> fromPhysicalDisplayId(DisplayId displayId) const = 0;
185 };
186 
187 namespace impl {
188 
189 class HWComposer final : public android::HWComposer {
190 public:
191     explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer);
192 
193     ~HWComposer() override;
194 
195     void registerCallback(HWC2::ComposerCallback* callback, int32_t sequenceId) override;
196 
197     bool getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
198                                       DisplayIdentificationData* outData) const override;
199 
200     bool hasCapability(HWC2::Capability capability) const override;
201     bool hasDisplayCapability(const std::optional<DisplayId>& displayId,
202                               HWC2::DisplayCapability capability) const override;
203 
204     // Attempts to allocate a virtual display and returns its ID if created on the HWC device.
205     std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
206                                                     ui::PixelFormat* format) override;
207 
208     // Attempts to create a new layer on this display
209     HWC2::Layer* createLayer(DisplayId displayId) override;
210     // Destroy a previously created layer
211     void destroyLayer(DisplayId displayId, HWC2::Layer* layer) override;
212 
213     // Asks the HAL what it can do
214     status_t prepare(DisplayId displayId, const compositionengine::Output&) override;
215 
216     status_t setClientTarget(DisplayId displayId, uint32_t slot, const sp<Fence>& acquireFence,
217                              const sp<GraphicBuffer>& target, ui::Dataspace dataspace) override;
218 
219     // Present layers to the display and read releaseFences.
220     status_t presentAndGetReleaseFences(DisplayId displayId) override;
221 
222     // set power mode
223     status_t setPowerMode(DisplayId displayId, int mode) override;
224 
225     // set active config
226     status_t setActiveConfig(DisplayId displayId, size_t configId) override;
227 
228     // Sets a color transform to be applied to the result of composition
229     status_t setColorTransform(DisplayId displayId, const mat4& transform) override;
230 
231     // reset state when an external, non-virtual display is disconnected
232     void disconnectDisplay(DisplayId displayId) override;
233 
234     // does this display have layers handled by HWC
235     bool hasDeviceComposition(const std::optional<DisplayId>& displayId) const override;
236 
237     // does this display have pending request to flip client target
238     bool hasFlipClientTargetRequest(const std::optional<DisplayId>& displayId) const override;
239 
240     // does this display have layers handled by GLES
241     bool hasClientComposition(const std::optional<DisplayId>& displayId) const override;
242 
243     // get the present fence received from the last call to present.
244     sp<Fence> getPresentFence(DisplayId displayId) const override;
245 
246     // Get last release fence for the given layer
247     sp<Fence> getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const override;
248 
249     // Set the output buffer and acquire fence for a virtual display.
250     // Returns INVALID_OPERATION if displayId is not a virtual display.
251     status_t setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence,
252                              const sp<GraphicBuffer>& buffer) override;
253 
254     // After SurfaceFlinger has retrieved the release fences for all the frames,
255     // it can call this to clear the shared pointers in the release fence map
256     void clearReleaseFences(DisplayId displayId) override;
257 
258     // Fetches the HDR capabilities of the given display
259     status_t getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities) override;
260 
261     int32_t getSupportedPerFrameMetadata(DisplayId displayId) const override;
262 
263     // Returns the available RenderIntent of the given display.
264     std::vector<ui::RenderIntent> getRenderIntents(DisplayId displayId,
265                                                    ui::ColorMode colorMode) const override;
266 
267     mat4 getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace) override;
268 
269     // Returns the attributes of the color sampling engine.
270     status_t getDisplayedContentSamplingAttributes(DisplayId displayId, ui::PixelFormat* outFormat,
271                                                    ui::Dataspace* outDataspace,
272                                                    uint8_t* outComponentMask) override;
273     status_t setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
274                                               uint8_t componentMask, uint64_t maxFrames) override;
275     status_t getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames, uint64_t timestamp,
276                                        DisplayedFrameStats* outStats) override;
277     status_t setDisplayBrightness(DisplayId displayId, float brightness) override;
278 
279     // Events handling ---------------------------------------------------------
280 
281     // Returns stable display ID (and display name on connection of new or previously disconnected
282     // display), or std::nullopt if hotplug event was ignored.
283     std::optional<DisplayIdentificationInfo> onHotplug(hwc2_display_t hwcDisplayId,
284                                                        HWC2::Connection connection) override;
285 
286     bool onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp) override;
287     void setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled) override;
288 
289     nsecs_t getRefreshTimestamp(DisplayId displayId) const override;
290     bool isConnected(DisplayId displayId) const override;
291 
292     // Non-const because it can update configMap inside of mDisplayData
293     std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(
294             DisplayId displayId) const override;
295 
296     std::shared_ptr<const HWC2::Display::Config> getActiveConfig(
297             DisplayId displayId) const override;
298     int getActiveConfigIndex(DisplayId displayId) const override;
299 
300     std::vector<ui::ColorMode> getColorModes(DisplayId displayId) const override;
301 
302     status_t setActiveColorMode(DisplayId displayId, ui::ColorMode mode,
303                                 ui::RenderIntent renderIntent) override;
304 
305     bool isUsingVrComposer() const override;
306 
307     // for debugging ----------------------------------------------------------
308     void dump(std::string& out) const override;
309 
getComposer()310     Hwc2::Composer* getComposer() const override { return mHwcDevice->getComposer(); }
311 
312     // TODO(b/74619554): Remove special cases for internal/external display.
getInternalHwcDisplayId()313     std::optional<hwc2_display_t> getInternalHwcDisplayId() const override {
314         return mInternalHwcDisplayId;
315     }
getExternalHwcDisplayId()316     std::optional<hwc2_display_t> getExternalHwcDisplayId() const override {
317         return mExternalHwcDisplayId;
318     }
319 
320     std::optional<DisplayId> toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const override;
321     std::optional<hwc2_display_t> fromPhysicalDisplayId(DisplayId displayId) const override;
322 
323 private:
324     // For unit tests
325     friend TestableSurfaceFlinger;
326 
327     std::optional<DisplayIdentificationInfo> onHotplugConnect(hwc2_display_t hwcDisplayId);
328 
329     static void validateChange(HWC2::Composition from, HWC2::Composition to);
330 
331     struct DisplayData {
332         bool isVirtual = false;
333         bool hasClientComposition = false;
334         bool hasDeviceComposition = false;
335         HWC2::Display* hwcDisplay = nullptr;
336         HWC2::DisplayRequest displayRequests;
337         sp<Fence> lastPresentFence = Fence::NO_FENCE; // signals when the last set op retires
338         std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
339         buffer_handle_t outbufHandle = nullptr;
340         sp<Fence> outbufAcquireFence = Fence::NO_FENCE;
341         mutable std::unordered_map<int32_t,
342                 std::shared_ptr<const HWC2::Display::Config>> configMap;
343 
344         bool validateWasSkipped;
345         HWC2::Error presentError;
346 
347         bool vsyncTraceToggle = false;
348 
349         std::mutex vsyncEnabledLock;
350         HWC2::Vsync vsyncEnabled GUARDED_BY(vsyncEnabledLock) = HWC2::Vsync::Disable;
351 
352         mutable std::mutex lastHwVsyncLock;
353         nsecs_t lastHwVsync GUARDED_BY(lastHwVsyncLock) = 0;
354     };
355 
356     std::unordered_map<DisplayId, DisplayData> mDisplayData;
357 
358     // This must be destroyed before mDisplayData, because destructor may call back into HWComposer
359     // and look up DisplayData.
360     std::unique_ptr<HWC2::Device> mHwcDevice;
361 
362     std::unordered_map<hwc2_display_t, DisplayId> mPhysicalDisplayIdMap;
363     std::optional<hwc2_display_t> mInternalHwcDisplayId;
364     std::optional<hwc2_display_t> mExternalHwcDisplayId;
365     bool mHasMultiDisplaySupport = false;
366 
367     std::unordered_set<DisplayId> mFreeVirtualDisplayIds;
368     uint32_t mNextVirtualDisplayId = 0;
369     uint32_t mRemainingHwcVirtualDisplays{mHwcDevice->getMaxVirtualDisplayCount()};
370 };
371 
372 } // namespace impl
373 } // namespace android
374 
375 #endif // ANDROID_SF_HWCOMPOSER_H
376