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