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 <future>
22 #include <memory>
23 #include <mutex>
24 #include <optional>
25 #include <unordered_map>
26 #include <unordered_set>
27 #include <vector>
28 
29 #include <android-base/thread_annotations.h>
30 #include <ui/FenceTime.h>
31 
32 // TODO(b/129481165): remove the #pragma below and fix conversion issues
33 #pragma clang diagnostic push
34 #pragma clang diagnostic ignored "-Wconversion"
35 #pragma clang diagnostic ignored "-Wextra"
36 #include <ui/GraphicTypes.h>
37 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
38 
39 #include <utils/StrongPointer.h>
40 #include <utils/Timers.h>
41 
42 #include "DisplayIdentification.h"
43 #include "DisplayMode.h"
44 #include "HWC2.h"
45 #include "Hal.h"
46 
47 namespace android {
48 
49 namespace hal = hardware::graphics::composer::hal;
50 
51 struct DisplayedFrameStats;
52 class GraphicBuffer;
53 class TestableSurfaceFlinger;
54 struct CompositionInfo;
55 
56 namespace Hwc2 {
57 class Composer;
58 } // namespace Hwc2
59 
60 namespace compositionengine {
61 class Output;
62 } // namespace compositionengine
63 
64 struct KnownHWCGenericLayerMetadata {
65     const char* name;
66     const uint32_t id;
67 };
68 
69 // See the comment for SurfaceFlinger::getHwComposer for the thread safety rules for accessing
70 // this class.
71 class HWComposer {
72 public:
73     struct DeviceRequestedChanges {
74         using ChangedTypes = std::unordered_map<HWC2::Layer*, hal::Composition>;
75         using ClientTargetProperty = hal::ClientTargetProperty;
76         using DisplayRequests = hal::DisplayRequest;
77         using LayerRequests = std::unordered_map<HWC2::Layer*, hal::LayerRequest>;
78 
79         ChangedTypes changedTypes;
80         DisplayRequests displayRequests;
81         LayerRequests layerRequests;
82         ClientTargetProperty clientTargetProperty;
83     };
84 
85     struct HWCDisplayMode {
86         hal::HWConfigId hwcId;
87         int32_t width = -1;
88         int32_t height = -1;
89         nsecs_t vsyncPeriod = -1;
90         int32_t dpiX = -1;
91         int32_t dpiY = -1;
92         int32_t configGroup = -1;
93 
94         friend std::ostream& operator<<(std::ostream& os, const HWCDisplayMode& mode) {
95             return os << "id=" << mode.hwcId << " res=" << mode.width << "x" << mode.height
96                       << " vsyncPeriod=" << mode.vsyncPeriod << " dpi=" << mode.dpiX << "x"
97                       << mode.dpiY << " group=" << mode.configGroup;
98         }
99     };
100 
101     virtual ~HWComposer();
102 
103     virtual void setCallback(HWC2::ComposerCallback*) = 0;
104 
105     virtual bool getDisplayIdentificationData(hal::HWDisplayId, uint8_t* outPort,
106                                               DisplayIdentificationData* outData) const = 0;
107 
108     virtual bool hasCapability(hal::Capability) const = 0;
109     virtual bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const = 0;
110 
111     virtual size_t getMaxVirtualDisplayCount() const = 0;
112     virtual size_t getMaxVirtualDisplayDimension() const = 0;
113 
114     // Attempts to allocate a virtual display on the HWC. The maximum number of virtual displays
115     // supported by the HWC can be queried in advance, but allocation may fail for other reasons.
116     virtual bool allocateVirtualDisplay(HalVirtualDisplayId, ui::Size, ui::PixelFormat*) = 0;
117 
118     virtual void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) = 0;
119 
120     // Attempts to create a new layer on this display
121     virtual std::shared_ptr<HWC2::Layer> createLayer(HalDisplayId) = 0;
122 
123     // Gets any required composition change requests from the HWC device.
124     //
125     // Note that frameUsesClientComposition must be set correctly based on
126     // whether the current frame appears to use client composition. If it is
127     // false some internal optimizations are allowed to present the display
128     // with fewer handshakes, but this does not work if client composition is
129     // expected.
130     virtual status_t getDeviceCompositionChanges(
131             HalDisplayId, bool frameUsesClientComposition,
132             std::chrono::steady_clock::time_point earliestPresentTime,
133             const std::shared_ptr<FenceTime>& previousPresentFence,
134             std::optional<DeviceRequestedChanges>* outChanges) = 0;
135 
136     virtual status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence,
137                                      const sp<GraphicBuffer>& target, ui::Dataspace) = 0;
138 
139     // Present layers to the display and read releaseFences.
140     virtual status_t presentAndGetReleaseFences(
141             HalDisplayId, std::chrono::steady_clock::time_point earliestPresentTime,
142             const std::shared_ptr<FenceTime>& previousPresentFence) = 0;
143 
144     // set power mode
145     virtual status_t setPowerMode(PhysicalDisplayId, hal::PowerMode) = 0;
146 
147     // Sets a color transform to be applied to the result of composition
148     virtual status_t setColorTransform(HalDisplayId, const mat4& transform) = 0;
149 
150     // reset state when a display is disconnected
151     virtual void disconnectDisplay(HalDisplayId) = 0;
152 
153     // get the present fence received from the last call to present.
154     virtual sp<Fence> getPresentFence(HalDisplayId) const = 0;
155 
156     // Get last release fence for the given layer
157     virtual sp<Fence> getLayerReleaseFence(HalDisplayId, HWC2::Layer*) const = 0;
158 
159     // Set the output buffer and acquire fence for a virtual display.
160     virtual status_t setOutputBuffer(HalVirtualDisplayId, const sp<Fence>& acquireFence,
161                                      const sp<GraphicBuffer>& buffer) = 0;
162 
163     // After SurfaceFlinger has retrieved the release fences for all the frames,
164     // it can call this to clear the shared pointers in the release fence map
165     virtual void clearReleaseFences(HalDisplayId) = 0;
166 
167     // Fetches the HDR capabilities of the given display
168     virtual status_t getHdrCapabilities(HalDisplayId, HdrCapabilities* outCapabilities) = 0;
169 
170     virtual int32_t getSupportedPerFrameMetadata(HalDisplayId) const = 0;
171 
172     // Returns the available RenderIntent of the given display.
173     virtual std::vector<ui::RenderIntent> getRenderIntents(HalDisplayId, ui::ColorMode) const = 0;
174 
175     virtual mat4 getDataspaceSaturationMatrix(HalDisplayId, ui::Dataspace) = 0;
176 
177     // Returns the attributes of the color sampling engine.
178     virtual status_t getDisplayedContentSamplingAttributes(HalDisplayId, ui::PixelFormat* outFormat,
179                                                            ui::Dataspace* outDataspace,
180                                                            uint8_t* outComponentMask) = 0;
181     virtual status_t setDisplayContentSamplingEnabled(HalDisplayId, bool enabled,
182                                                       uint8_t componentMask,
183                                                       uint64_t maxFrames) = 0;
184     virtual status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp,
185                                                DisplayedFrameStats* outStats) = 0;
186 
187     // Sets the brightness of a display.
188     virtual std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) = 0;
189 
190     // Events handling ---------------------------------------------------------
191 
192     // Returns stable display ID (and display name on connection of new or previously disconnected
193     // display), or std::nullopt if hotplug event was ignored.
194     // This function is called from SurfaceFlinger.
195     virtual std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId,
196                                                                hal::Connection) = 0;
197 
198     // If true we'll update the DeviceProductInfo on subsequent hotplug connected events.
199     // TODO(b/157555476): Remove when the framework has proper support for headless mode
200     virtual bool updatesDeviceProductInfoOnHotplugReconnect() const = 0;
201 
202     virtual bool onVsync(hal::HWDisplayId, int64_t timestamp) = 0;
203     virtual void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) = 0;
204 
205     virtual bool isConnected(PhysicalDisplayId) const = 0;
206 
207     virtual std::vector<HWCDisplayMode> getModes(PhysicalDisplayId) const = 0;
208 
209     virtual std::optional<hal::HWConfigId> getActiveMode(PhysicalDisplayId) const = 0;
210 
211     virtual std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const = 0;
212 
213     virtual status_t setActiveColorMode(PhysicalDisplayId, ui::ColorMode mode,
214                                         ui::RenderIntent) = 0;
215 
216     // Composer 2.4
217     virtual ui::DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const = 0;
218     virtual bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const = 0;
219     virtual status_t getDisplayVsyncPeriod(PhysicalDisplayId displayId,
220                                            nsecs_t* outVsyncPeriod) const = 0;
221     virtual status_t setActiveModeWithConstraints(PhysicalDisplayId, hal::HWConfigId,
222                                                   const hal::VsyncPeriodChangeConstraints&,
223                                                   hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
224     virtual status_t setAutoLowLatencyMode(PhysicalDisplayId, bool on) = 0;
225     virtual status_t getSupportedContentTypes(
226             PhysicalDisplayId, std::vector<hal::ContentType>* outSupportedContentTypes) = 0;
227     virtual status_t setContentType(PhysicalDisplayId, hal::ContentType) = 0;
228     virtual const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata()
229             const = 0;
230 
231     // for debugging ----------------------------------------------------------
232     virtual void dump(std::string& out) const = 0;
233 
234     virtual Hwc2::Composer* getComposer() const = 0;
235 
236     // TODO(b/74619554): Remove special cases for internal/external display.
237     virtual std::optional<hal::HWDisplayId> getInternalHwcDisplayId() const = 0;
238     virtual std::optional<hal::HWDisplayId> getExternalHwcDisplayId() const = 0;
239 
240     virtual std::optional<PhysicalDisplayId> toPhysicalDisplayId(hal::HWDisplayId) const = 0;
241     virtual std::optional<hal::HWDisplayId> fromPhysicalDisplayId(PhysicalDisplayId) const = 0;
242 };
243 
244 namespace impl {
245 
246 class HWComposer final : public android::HWComposer {
247 public:
248     explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer);
249     explicit HWComposer(const std::string& composerServiceName);
250 
251     ~HWComposer() override;
252 
253     void setCallback(HWC2::ComposerCallback*) override;
254 
255     bool getDisplayIdentificationData(hal::HWDisplayId, uint8_t* outPort,
256                                       DisplayIdentificationData* outData) const override;
257 
258     bool hasCapability(hal::Capability) const override;
259     bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const override;
260 
261     size_t getMaxVirtualDisplayCount() const override;
262     size_t getMaxVirtualDisplayDimension() const override;
263 
264     bool allocateVirtualDisplay(HalVirtualDisplayId, ui::Size, ui::PixelFormat*) override;
265 
266     // Called from SurfaceFlinger, when the state for a new physical display needs to be recreated.
267     void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) override;
268 
269     // Attempts to create a new layer on this display
270     std::shared_ptr<HWC2::Layer> createLayer(HalDisplayId) override;
271 
272     status_t getDeviceCompositionChanges(
273             HalDisplayId, bool frameUsesClientComposition,
274             std::chrono::steady_clock::time_point earliestPresentTime,
275             const std::shared_ptr<FenceTime>& previousPresentFence,
276             std::optional<DeviceRequestedChanges>* outChanges) override;
277 
278     status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence,
279                              const sp<GraphicBuffer>& target, ui::Dataspace) override;
280 
281     // Present layers to the display and read releaseFences.
282     status_t presentAndGetReleaseFences(
283             HalDisplayId, std::chrono::steady_clock::time_point earliestPresentTime,
284             const std::shared_ptr<FenceTime>& previousPresentFence) override;
285 
286     // set power mode
287     status_t setPowerMode(PhysicalDisplayId, hal::PowerMode mode) override;
288 
289     // Sets a color transform to be applied to the result of composition
290     status_t setColorTransform(HalDisplayId, const mat4& transform) override;
291 
292     // reset state when a display is disconnected
293     void disconnectDisplay(HalDisplayId) override;
294 
295     // get the present fence received from the last call to present.
296     sp<Fence> getPresentFence(HalDisplayId) const override;
297 
298     // Get last release fence for the given layer
299     sp<Fence> getLayerReleaseFence(HalDisplayId, HWC2::Layer*) const override;
300 
301     // Set the output buffer and acquire fence for a virtual display.
302     status_t setOutputBuffer(HalVirtualDisplayId, const sp<Fence>& acquireFence,
303                              const sp<GraphicBuffer>& buffer) override;
304 
305     // After SurfaceFlinger has retrieved the release fences for all the frames,
306     // it can call this to clear the shared pointers in the release fence map
307     void clearReleaseFences(HalDisplayId) override;
308 
309     // Fetches the HDR capabilities of the given display
310     status_t getHdrCapabilities(HalDisplayId, HdrCapabilities* outCapabilities) override;
311 
312     int32_t getSupportedPerFrameMetadata(HalDisplayId) const override;
313 
314     // Returns the available RenderIntent of the given display.
315     std::vector<ui::RenderIntent> getRenderIntents(HalDisplayId, ui::ColorMode) const override;
316 
317     mat4 getDataspaceSaturationMatrix(HalDisplayId, ui::Dataspace) override;
318 
319     // Returns the attributes of the color sampling engine.
320     status_t getDisplayedContentSamplingAttributes(HalDisplayId, ui::PixelFormat* outFormat,
321                                                    ui::Dataspace* outDataspace,
322                                                    uint8_t* outComponentMask) override;
323     status_t setDisplayContentSamplingEnabled(HalDisplayId, bool enabled, uint8_t componentMask,
324                                               uint64_t maxFrames) override;
325     status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp,
326                                        DisplayedFrameStats* outStats) override;
327     std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) override;
328 
329     // Events handling ---------------------------------------------------------
330 
331     // Returns PhysicalDisplayId (and display name on connection of new or previously disconnected
332     // display), or std::nullopt if hotplug event was ignored.
333     std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId, hal::Connection) override;
334 
335     bool updatesDeviceProductInfoOnHotplugReconnect() const override;
336 
337     bool onVsync(hal::HWDisplayId, int64_t timestamp) override;
338     void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) override;
339 
340     bool isConnected(PhysicalDisplayId) const override;
341 
342     std::vector<HWCDisplayMode> getModes(PhysicalDisplayId) const override;
343 
344     std::optional<hal::HWConfigId> getActiveMode(PhysicalDisplayId) const override;
345 
346     std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const override;
347 
348     status_t setActiveColorMode(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent) override;
349 
350     // Composer 2.4
351     ui::DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const override;
352     bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const override;
353     status_t getDisplayVsyncPeriod(PhysicalDisplayId displayId,
354                                    nsecs_t* outVsyncPeriod) const override;
355     status_t setActiveModeWithConstraints(PhysicalDisplayId, hal::HWConfigId,
356                                           const hal::VsyncPeriodChangeConstraints&,
357                                           hal::VsyncPeriodChangeTimeline* outTimeline) override;
358     status_t setAutoLowLatencyMode(PhysicalDisplayId, bool) override;
359     status_t getSupportedContentTypes(PhysicalDisplayId, std::vector<hal::ContentType>*) override;
360     status_t setContentType(PhysicalDisplayId, hal::ContentType) override;
361 
362     const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata() const override;
363 
364     // for debugging ----------------------------------------------------------
365     void dump(std::string& out) const override;
366 
getComposer()367     Hwc2::Composer* getComposer() const override { return mComposer.get(); }
368 
369     // TODO(b/74619554): Remove special cases for internal/external display.
getInternalHwcDisplayId()370     std::optional<hal::HWDisplayId> getInternalHwcDisplayId() const override {
371         return mInternalHwcDisplayId;
372     }
getExternalHwcDisplayId()373     std::optional<hal::HWDisplayId> getExternalHwcDisplayId() const override {
374         return mExternalHwcDisplayId;
375     }
376 
377     std::optional<PhysicalDisplayId> toPhysicalDisplayId(hal::HWDisplayId) const override;
378     std::optional<hal::HWDisplayId> fromPhysicalDisplayId(PhysicalDisplayId) const override;
379 
380 private:
381     // For unit tests
382     friend TestableSurfaceFlinger;
383 
384     struct DisplayData {
385         bool isVirtual = false;
386         std::unique_ptr<HWC2::Display> hwcDisplay;
387         sp<Fence> lastPresentFence = Fence::NO_FENCE; // signals when the last set op retires
388         std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
389         buffer_handle_t outbufHandle = nullptr;
390         sp<Fence> outbufAcquireFence = Fence::NO_FENCE;
391 
392         bool validateWasSkipped;
393         hal::Error presentError;
394 
395         bool vsyncTraceToggle = false;
396 
397         std::mutex vsyncEnabledLock;
398         hal::Vsync vsyncEnabled GUARDED_BY(vsyncEnabledLock) = hal::Vsync::DISABLE;
399 
400         nsecs_t lastHwVsync = 0;
401     };
402 
403     std::optional<DisplayIdentificationInfo> onHotplugConnect(hal::HWDisplayId);
404     std::optional<DisplayIdentificationInfo> onHotplugDisconnect(hal::HWDisplayId);
405     bool shouldIgnoreHotplugConnect(hal::HWDisplayId, bool hasDisplayIdentificationData) const;
406 
407     int32_t getAttribute(hal::HWDisplayId hwcDisplayId, hal::HWConfigId configId,
408                          hal::Attribute attribute) const;
409 
410     void loadCapabilities();
411     void loadLayerMetadataSupport();
412 
413     std::unordered_map<HalDisplayId, DisplayData> mDisplayData;
414 
415     std::unique_ptr<android::Hwc2::Composer> mComposer;
416     std::unordered_set<hal::Capability> mCapabilities;
417     std::unordered_map<std::string, bool> mSupportedLayerGenericMetadata;
418     bool mRegisteredCallback = false;
419 
420     std::unordered_map<hal::HWDisplayId, PhysicalDisplayId> mPhysicalDisplayIdMap;
421     std::optional<hal::HWDisplayId> mInternalHwcDisplayId;
422     std::optional<hal::HWDisplayId> mExternalHwcDisplayId;
423     bool mHasMultiDisplaySupport = false;
424 
425     const size_t mMaxVirtualDisplayDimension;
426     const bool mUpdateDeviceProductInfoOnHotplugReconnect;
427 };
428 
429 } // namespace impl
430 } // namespace android
431 
432 #endif // ANDROID_SF_HWCOMPOSER_H
433