xref: /aosp_15_r20/external/drm_hwcomposer/hwc2_device/HwcDisplay.h (revision 0a9764fe0a15e71ebbeb85e87e10990c23aab47f)
1 /*
2  * Copyright (C) 2022 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 <hardware/hwcomposer2.h>
20 
21 #include <atomic>
22 #include <optional>
23 #include <sstream>
24 
25 #include "HwcDisplayConfigs.h"
26 #include "compositor/DisplayInfo.h"
27 #include "compositor/FlatteningController.h"
28 #include "compositor/LayerData.h"
29 #include "drm/DrmAtomicStateManager.h"
30 #include "drm/ResourceManager.h"
31 #include "drm/VSyncWorker.h"
32 #include "hwc2_device/HwcLayer.h"
33 
34 namespace android {
35 
36 class Backend;
37 class DrmHwc;
38 
39 inline constexpr uint32_t kPrimaryDisplay = 0;
40 
41 // NOLINTNEXTLINE
42 class HwcDisplay {
43  public:
44   enum ConfigError {
45     kNone,
46     kBadConfig,
47     kSeamlessNotAllowed,
48     kSeamlessNotPossible
49   };
50 
51   HwcDisplay(hwc2_display_t handle, HWC2::DisplayType type, DrmHwc *hwc);
52   HwcDisplay(const HwcDisplay &) = delete;
53   ~HwcDisplay();
54 
55   /* SetPipeline should be carefully used only by DrmHwcTwo hotplug handlers */
56   void SetPipeline(std::shared_ptr<DrmDisplayPipeline> pipeline);
57 
58   HWC2::Error CreateComposition(AtomicCommitArgs &a_args);
59   std::vector<HwcLayer *> GetOrderLayersByZPos();
60 
61   void ClearDisplay();
62 
63   std::string Dump();
64 
GetDisplayConfigs()65   const HwcDisplayConfigs &GetDisplayConfigs() const {
66     return configs_;
67   }
68 
69   // Get the config representing the mode that has been committed to KMS.
70   auto GetCurrentConfig() const -> const HwcDisplayConfig *;
71 
72   // Get the config that was last requested through SetActiveConfig and similar
73   // functions. This may differ from the GetCurrentConfig if the config change
74   // is queued up to take effect in the future.
75   auto GetLastRequestedConfig() const -> const HwcDisplayConfig *;
76 
77   // Set a config synchronously. If the requested config fails to be committed,
78   // this will return with an error. Otherwise, the config will have been
79   // committed to the kernel on successful return.
80   ConfigError SetConfig(hwc2_config_t config);
81 
82   // Queue a configuration change to take effect in the future.
83   auto QueueConfig(hwc2_config_t config, int64_t desired_time, bool seamless,
84                    QueuedConfigTiming *out_timing) -> ConfigError;
85 
86   // Get the HwcDisplayConfig, or nullptor if none.
87   auto GetConfig(hwc2_config_t config_id) const -> const HwcDisplayConfig *;
88 
89   // HWC2 Hooks - these should not be used outside of the hwc2 device.
90   HWC2::Error AcceptDisplayChanges();
91   HWC2::Error CreateLayer(hwc2_layer_t *layer);
92   HWC2::Error DestroyLayer(hwc2_layer_t layer);
93   HWC2::Error GetActiveConfig(hwc2_config_t *config) const;
94   HWC2::Error GetChangedCompositionTypes(uint32_t *num_elements,
95                                          hwc2_layer_t *layers, int32_t *types);
96   HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height,
97                                      int32_t format, int32_t dataspace);
98   HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes);
99   HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute,
100                                   int32_t *value);
101   HWC2::Error LegacyGetDisplayConfigs(uint32_t *num_configs,
102                                       hwc2_config_t *configs);
103   HWC2::Error GetDisplayName(uint32_t *size, char *name);
104   HWC2::Error GetDisplayRequests(int32_t *display_requests,
105                                  uint32_t *num_elements, hwc2_layer_t *layers,
106                                  int32_t *layer_requests);
107   HWC2::Error GetDisplayType(int32_t *type);
108 #if __ANDROID_API__ > 27
109   HWC2::Error GetRenderIntents(int32_t mode, uint32_t *outNumIntents,
110                                int32_t *outIntents);
111   HWC2::Error SetColorModeWithIntent(int32_t mode, int32_t intent);
112 #endif
113 #if __ANDROID_API__ > 28
114   HWC2::Error GetDisplayIdentificationData(uint8_t *outPort,
115                                            uint32_t *outDataSize,
116                                            uint8_t *outData);
117   HWC2::Error GetDisplayCapabilities(uint32_t *outNumCapabilities,
118                                      uint32_t *outCapabilities);
119   HWC2::Error GetDisplayBrightnessSupport(bool *supported);
120   HWC2::Error SetDisplayBrightness(float);
121 #endif
122 #if __ANDROID_API__ > 29
123   HWC2::Error GetDisplayConnectionType(uint32_t *outType);
124 
125   HWC2::Error SetActiveConfigWithConstraints(
126       hwc2_config_t config,
127       hwc_vsync_period_change_constraints_t *vsyncPeriodChangeConstraints,
128       hwc_vsync_period_change_timeline_t *outTimeline);
129   HWC2::Error SetAutoLowLatencyMode(bool on);
130   HWC2::Error GetSupportedContentTypes(
131       uint32_t *outNumSupportedContentTypes,
132       const uint32_t *outSupportedContentTypes);
133 
134   HWC2::Error SetContentType(int32_t contentType);
135 #endif
136   HWC2::Error GetDisplayVsyncPeriod(uint32_t *outVsyncPeriod);
137 
138   HWC2::Error GetDozeSupport(int32_t *support);
139   HWC2::Error GetHdrCapabilities(uint32_t *num_types, int32_t *types,
140                                  float *max_luminance,
141                                  float *max_average_luminance,
142                                  float *min_luminance);
143   HWC2::Error GetReleaseFences(uint32_t *num_elements, hwc2_layer_t *layers,
144                                int32_t *fences);
145   HWC2::Error PresentDisplay(int32_t *out_present_fence);
146   HWC2::Error SetActiveConfig(hwc2_config_t config);
147   HWC2::Error ChosePreferredConfig();
148   HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
149                               int32_t dataspace, hwc_region_t damage);
150   HWC2::Error SetColorMode(int32_t mode);
151   HWC2::Error SetColorTransform(const float *matrix, int32_t hint);
152   HWC2::Error SetOutputBuffer(buffer_handle_t buffer, int32_t release_fence);
153   HWC2::Error SetPowerMode(int32_t mode);
154   HWC2::Error SetVsyncEnabled(int32_t enabled);
155   HWC2::Error ValidateDisplay(uint32_t *num_types, uint32_t *num_requests);
get_layer(hwc2_layer_t layer)156   HwcLayer *get_layer(hwc2_layer_t layer) {
157     auto it = layers_.find(layer);
158     if (it == layers_.end())
159       return nullptr;
160     return &it->second;
161   }
162 
163   /* Statistics */
164   struct Stats {
minusStats165     Stats minus(Stats b) const {
166       return {total_frames_ - b.total_frames_,
167               total_pixops_ - b.total_pixops_,
168               gpu_pixops_ - b.gpu_pixops_,
169               failed_kms_validate_ - b.failed_kms_validate_,
170               failed_kms_present_ - b.failed_kms_present_,
171               frames_flattened_ - b.frames_flattened_};
172     }
173 
174     uint32_t total_frames_ = 0;
175     uint64_t total_pixops_ = 0;
176     uint64_t gpu_pixops_ = 0;
177     uint32_t failed_kms_validate_ = 0;
178     uint32_t failed_kms_present_ = 0;
179     uint32_t frames_flattened_ = 0;
180   };
181 
182   const Backend *backend() const;
183   void set_backend(std::unique_ptr<Backend> backend);
184 
GetHwc()185   auto GetHwc() {
186     return hwc_;
187   }
188 
layers()189   std::map<hwc2_layer_t, HwcLayer> &layers() {
190     return layers_;
191   }
192 
GetPipe()193   auto &GetPipe() {
194     return *pipeline_;
195   }
196 
197   bool CtmByGpu();
198 
total_stats()199   Stats &total_stats() {
200     return total_stats_;
201   }
202 
203   /* Headless mode required to keep SurfaceFlinger alive when all display are
204    * disconnected, Without headless mode Android will continuously crash.
205    * Only single internal (primary) display is required to be in HEADLESS mode
206    * to prevent the crash. See:
207    * https://source.android.com/devices/graphics/hotplug#handling-common-scenarios
208    */
IsInHeadlessMode()209   bool IsInHeadlessMode() {
210     return !pipeline_;
211   }
212 
213   void Deinit();
214 
GetFlatCon()215   auto GetFlatCon() {
216     return flatcon_;
217   }
218 
GetWritebackLayer()219   auto &GetWritebackLayer() {
220     return writeback_layer_;
221   }
222 
SetVirtualDisplayResolution(uint16_t width,uint16_t height)223   void SetVirtualDisplayResolution(uint16_t width, uint16_t height) {
224     virtual_disp_width_ = width;
225     virtual_disp_height_ = height;
226   }
227 
228   auto getDisplayPhysicalOrientation() -> std::optional<PanelOrientation>;
229 
230  private:
231   AtomicCommitArgs CreateModesetCommit(
232       const HwcDisplayConfig *config,
233       const std::optional<LayerData> &modeset_layer);
234 
235   HwcDisplayConfigs configs_;
236 
237   DrmHwc *const hwc_;
238 
239   SharedFd present_fence_;
240 
241   int64_t staged_mode_change_time_{};
242   std::optional<uint32_t> staged_mode_config_id_{};
243 
244   std::shared_ptr<DrmDisplayPipeline> pipeline_;
245 
246   std::unique_ptr<Backend> backend_;
247   std::shared_ptr<FlatteningController> flatcon_;
248 
249   std::shared_ptr<VSyncWorker> vsync_worker_;
250   bool vsync_event_en_{};
251   bool vsync_tracking_en_{};
252   int64_t last_vsync_ts_{};
253 
254   const hwc2_display_t handle_;
255   HWC2::DisplayType type_;
256 
257   uint32_t layer_idx_{};
258 
259   std::map<hwc2_layer_t, HwcLayer> layers_;
260   HwcLayer client_layer_;
261   std::unique_ptr<HwcLayer> writeback_layer_;
262   uint16_t virtual_disp_width_{};
263   uint16_t virtual_disp_height_{};
264   int32_t color_mode_{};
265   static constexpr int kCtmRows = 3;
266   static constexpr int kCtmCols = 3;
267   std::shared_ptr<drm_color_ctm> color_matrix_;
268   android_color_transform_t color_transform_hint_{};
269   int32_t content_type_{};
270   Colorspace colorspace_{};
271 
272   std::shared_ptr<DrmKmsPlan> current_plan_;
273 
274   uint32_t frame_no_ = 0;
275   Stats total_stats_;
276   Stats prev_stats_;
277   std::string DumpDelta(HwcDisplay::Stats delta);
278 
279   void SetColorMatrixToIdentity();
280 
281   HWC2::Error Init();
282 
283   HWC2::Error SetActiveConfigInternal(uint32_t config, int64_t change_time);
284 };
285 
286 }  // namespace android
287