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 <ui/GraphicTypes.h> 26 27 #include "HwcDisplayConfigs.h" 28 #include "compositor/DisplayInfo.h" 29 #include "compositor/FlatteningController.h" 30 #include "compositor/LayerData.h" 31 #include "drm/DrmAtomicStateManager.h" 32 #include "drm/ResourceManager.h" 33 #include "drm/VSyncWorker.h" 34 #include "hwc2_device/HwcLayer.h" 35 36 namespace android { 37 38 class Backend; 39 class DrmHwc; 40 41 class FrontendDisplayBase { 42 public: 43 virtual ~FrontendDisplayBase() = default; 44 }; 45 46 inline constexpr uint32_t kPrimaryDisplay = 0; 47 48 // NOLINTNEXTLINE 49 class HwcDisplay { 50 public: 51 enum ConfigError { 52 kNone, 53 kBadConfig, 54 kSeamlessNotAllowed, 55 kSeamlessNotPossible, 56 kConfigFailed, 57 }; 58 59 HwcDisplay(hwc2_display_t handle, HWC2::DisplayType type, DrmHwc *hwc); 60 HwcDisplay(const HwcDisplay &) = delete; 61 ~HwcDisplay(); 62 63 void SetColorTransformMatrix( 64 const std::array<float, 16> &color_transform_matrix); 65 66 /* SetPipeline should be carefully used only by DrmHwcTwo hotplug handlers */ 67 void SetPipeline(std::shared_ptr<DrmDisplayPipeline> pipeline); 68 69 HWC2::Error CreateComposition(AtomicCommitArgs &a_args); 70 std::vector<HwcLayer *> GetOrderLayersByZPos(); 71 72 void ClearDisplay(); 73 74 std::string Dump(); 75 GetDisplayConfigs()76 const HwcDisplayConfigs &GetDisplayConfigs() const { 77 return configs_; 78 } 79 80 // Get the config representing the mode that has been committed to KMS. 81 auto GetCurrentConfig() const -> const HwcDisplayConfig *; 82 83 // Get the config that was last requested through SetActiveConfig and similar 84 // functions. This may differ from the GetCurrentConfig if the config change 85 // is queued up to take effect in the future. 86 auto GetLastRequestedConfig() const -> const HwcDisplayConfig *; 87 88 // Set a config synchronously. If the requested config fails to be committed, 89 // this will return with an error. Otherwise, the config will have been 90 // committed to the kernel on successful return. 91 ConfigError SetConfig(hwc2_config_t config); 92 93 // Queue a configuration change to take effect in the future. 94 auto QueueConfig(hwc2_config_t config, int64_t desired_time, bool seamless, 95 QueuedConfigTiming *out_timing) -> ConfigError; 96 97 // Get the HwcDisplayConfig, or nullptor if none. 98 auto GetConfig(hwc2_config_t config_id) const -> const HwcDisplayConfig *; 99 100 auto GetDisplayBoundsMm() -> std::pair<int32_t, int32_t>; 101 102 // To be called after SetDisplayProperties. Returns an empty vector if the 103 // requested layers have been validated, otherwise the vector describes 104 // the requested composition type changes. 105 using ChangedLayer = std::pair<ILayerId, HWC2::Composition>; 106 auto ValidateStagedComposition() -> std::vector<ChangedLayer>; 107 108 // Mark previously validated properties as ready to present. 109 auto AcceptValidatedComposition() -> void; 110 111 using ReleaseFence = std::pair<ILayerId, SharedFd>; 112 // Present previously staged properties, and return fences to indicate when 113 // the new content has been presented, and when the previous buffers have 114 // been released. If |desired_present_time| is set, ensure that the 115 // composition is presented at the closest vsync to that requested time. 116 // Otherwise, present immediately. 117 auto PresentStagedComposition(std::optional<int64_t> desired_present_time, 118 SharedFd &out_present_fence, 119 std::vector<ReleaseFence> &out_release_fences) 120 -> bool; 121 122 auto GetFrontendPrivateData() -> std::shared_ptr<FrontendDisplayBase> { 123 return frontend_private_data_; 124 } 125 SetFrontendPrivateData(std::shared_ptr<FrontendDisplayBase> data)126 auto SetFrontendPrivateData(std::shared_ptr<FrontendDisplayBase> data) { 127 frontend_private_data_ = std::move(data); 128 } 129 130 auto CreateLayer(ILayerId new_layer_id) -> bool; 131 auto DestroyLayer(ILayerId layer_id) -> bool; 132 133 // HWC2 Hooks - these should not be used outside of the hwc2 device. 134 HWC2::Error GetActiveConfig(hwc2_config_t *config) const; 135 HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes); 136 HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute, 137 int32_t *value); 138 HWC2::Error LegacyGetDisplayConfigs(uint32_t *num_configs, 139 hwc2_config_t *configs); 140 HWC2::Error GetDisplayName(uint32_t *size, char *name); 141 HWC2::Error GetDisplayType(int32_t *type); 142 #if __ANDROID_API__ > 27 143 HWC2::Error GetRenderIntents(int32_t mode, uint32_t *outNumIntents, 144 int32_t *outIntents); 145 HWC2::Error SetColorModeWithIntent(int32_t mode, int32_t intent); 146 #endif 147 #if __ANDROID_API__ > 28 148 HWC2::Error GetDisplayIdentificationData(uint8_t *outPort, 149 uint32_t *outDataSize, 150 uint8_t *outData); 151 HWC2::Error GetDisplayCapabilities(uint32_t *outNumCapabilities, 152 uint32_t *outCapabilities); 153 #endif 154 #if __ANDROID_API__ > 29 155 HWC2::Error GetDisplayConnectionType(uint32_t *outType); 156 157 HWC2::Error SetActiveConfigWithConstraints( 158 hwc2_config_t config, 159 hwc_vsync_period_change_constraints_t *vsyncPeriodChangeConstraints, 160 hwc_vsync_period_change_timeline_t *outTimeline); 161 162 HWC2::Error SetContentType(int32_t contentType); 163 #endif 164 HWC2::Error GetDisplayVsyncPeriod(uint32_t *outVsyncPeriod); 165 166 HWC2::Error GetHdrCapabilities(uint32_t *num_types, int32_t *types, 167 float *max_luminance, 168 float *max_average_luminance, 169 float *min_luminance); 170 HWC2::Error SetActiveConfig(hwc2_config_t config); 171 HWC2::Error ChosePreferredConfig(); 172 HWC2::Error SetColorMode(int32_t mode); 173 HWC2::Error SetColorTransform(const float *matrix, int32_t hint); 174 HWC2::Error SetPowerMode(int32_t mode); 175 HWC2::Error SetVsyncEnabled(int32_t enabled); get_layer(ILayerId layer)176 HwcLayer *get_layer(ILayerId layer) { 177 auto it = layers_.find(layer); 178 if (it == layers_.end()) 179 return nullptr; 180 return &it->second; 181 } 182 183 /* Statistics */ 184 struct Stats { minusStats185 Stats minus(Stats b) const { 186 return {total_frames_ - b.total_frames_, 187 total_pixops_ - b.total_pixops_, 188 gpu_pixops_ - b.gpu_pixops_, 189 failed_kms_validate_ - b.failed_kms_validate_, 190 failed_kms_present_ - b.failed_kms_present_, 191 frames_flattened_ - b.frames_flattened_}; 192 } 193 194 uint32_t total_frames_ = 0; 195 uint64_t total_pixops_ = 0; 196 uint64_t gpu_pixops_ = 0; 197 uint32_t failed_kms_validate_ = 0; 198 uint32_t failed_kms_present_ = 0; 199 uint32_t frames_flattened_ = 0; 200 }; 201 202 const Backend *backend() const; 203 void set_backend(std::unique_ptr<Backend> backend); 204 GetHwc()205 auto GetHwc() { 206 return hwc_; 207 } 208 209 auto layers() -> std::map<ILayerId, HwcLayer> & { 210 return layers_; 211 } 212 GetPipe()213 auto &GetPipe() { 214 return *pipeline_; 215 } 216 217 bool CtmByGpu(); 218 total_stats()219 Stats &total_stats() { 220 return total_stats_; 221 } 222 223 /* Headless mode required to keep SurfaceFlinger alive when all display are 224 * disconnected, Without headless mode Android will continuously crash. 225 * Only single internal (primary) display is required to be in HEADLESS mode 226 * to prevent the crash. See: 227 * https://source.android.com/devices/graphics/hotplug#handling-common-scenarios 228 */ IsInHeadlessMode()229 bool IsInHeadlessMode() { 230 return !pipeline_; 231 } 232 233 void Deinit(); 234 GetFlatCon()235 auto GetFlatCon() { 236 return flatcon_; 237 } 238 239 auto GetClientLayer() -> HwcLayer & { 240 return client_layer_; 241 } 242 GetWritebackLayer()243 auto &GetWritebackLayer() { 244 return writeback_layer_; 245 } 246 SetVirtualDisplayResolution(uint16_t width,uint16_t height)247 void SetVirtualDisplayResolution(uint16_t width, uint16_t height) { 248 virtual_disp_width_ = width; 249 virtual_disp_height_ = height; 250 } 251 252 auto getDisplayPhysicalOrientation() -> std::optional<PanelOrientation>; 253 254 bool NeedsClientLayerUpdate() const; 255 256 private: 257 AtomicCommitArgs CreateModesetCommit( 258 const HwcDisplayConfig *config, 259 const std::optional<LayerData> &modeset_layer); 260 261 // Sleep the current thread until |present_time| is closest to the next 262 // expected vsync time. 263 void WaitForPresentTime(int64_t present_time, uint32_t vsync_period_ns); 264 265 HwcDisplayConfigs configs_; 266 267 DrmHwc *const hwc_; 268 269 int64_t staged_mode_change_time_{}; 270 std::optional<uint32_t> staged_mode_config_id_{}; 271 272 std::shared_ptr<DrmDisplayPipeline> pipeline_; 273 274 std::unique_ptr<Backend> backend_; 275 std::shared_ptr<FlatteningController> flatcon_; 276 277 std::unique_ptr<VSyncWorker> vsync_worker_; 278 bool vsync_event_en_{}; 279 280 const hwc2_display_t handle_; 281 HWC2::DisplayType type_; 282 283 std::map<ILayerId, HwcLayer> layers_; 284 HwcLayer client_layer_; 285 std::unique_ptr<HwcLayer> writeback_layer_; 286 uint16_t virtual_disp_width_{}; 287 uint16_t virtual_disp_height_{}; 288 int32_t color_mode_{}; 289 std::shared_ptr<drm_color_ctm> color_matrix_; 290 std::shared_ptr<drm_color_ctm> identity_color_matrix_; 291 android_color_transform_t color_transform_hint_{}; 292 bool ctm_has_offset_ = false; 293 int32_t content_type_{}; 294 Colorspace colorspace_{}; 295 int32_t min_bpc_{}; 296 std::shared_ptr<hdr_output_metadata> hdr_metadata_; 297 298 std::shared_ptr<DrmKmsPlan> current_plan_; 299 300 uint32_t frame_no_ = 0; 301 Stats total_stats_; 302 Stats prev_stats_; 303 std::string DumpDelta(HwcDisplay::Stats delta); 304 305 void SetColorMatrixToIdentity(); 306 307 HWC2::Error Init(); 308 309 HWC2::Error SetActiveConfigInternal(uint32_t config, int64_t change_time); 310 HWC2::Error SetHdrOutputMetadata(ui::Hdr hdrType); 311 HWC2::Error SetOutputType(uint32_t hdr_output_type); 312 313 auto GetEdid() -> EdidWrapperUnique & { 314 return GetPipe().connector->Get()->GetParsedEdid(); 315 } 316 317 std::shared_ptr<FrontendDisplayBase> frontend_private_data_; 318 }; 319 320 } // namespace android 321