1 /* 2 * Copyright (C) 2016 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 #include "drmdisplaycompositor.h" 18 #include "drmhwcomposer.h" 19 #include "platform.h" 20 #include "resourcemanager.h" 21 #include "vsyncworker.h" 22 23 #include <hardware/hwcomposer2.h> 24 25 #include <array> 26 #include <map> 27 28 namespace android { 29 30 class DrmHwcTwo : public hwc2_device_t { 31 public: 32 static int HookDevOpen(const struct hw_module_t *module, const char *name, 33 struct hw_device_t **dev); 34 35 DrmHwcTwo(); 36 37 HWC2::Error Init(); 38 39 private: 40 class HwcLayer { 41 public: sf_type()42 HWC2::Composition sf_type() const { 43 return sf_type_; 44 } validated_type()45 HWC2::Composition validated_type() const { 46 return validated_type_; 47 } accept_type_change()48 void accept_type_change() { 49 sf_type_ = validated_type_; 50 } set_validated_type(HWC2::Composition type)51 void set_validated_type(HWC2::Composition type) { 52 validated_type_ = type; 53 } type_changed()54 bool type_changed() const { 55 return sf_type_ != validated_type_; 56 } 57 z_order()58 uint32_t z_order() const { 59 return z_order_; 60 } 61 buffer()62 buffer_handle_t buffer() { 63 return buffer_; 64 } set_buffer(buffer_handle_t buffer)65 void set_buffer(buffer_handle_t buffer) { 66 buffer_ = buffer; 67 } 68 take_acquire_fence()69 int take_acquire_fence() { 70 return acquire_fence_.Release(); 71 } set_acquire_fence(int acquire_fence)72 void set_acquire_fence(int acquire_fence) { 73 acquire_fence_.Set(dup(acquire_fence)); 74 } 75 release_fence()76 int release_fence() { 77 return release_fence_.get(); 78 } take_release_fence()79 int take_release_fence() { 80 return release_fence_.Release(); 81 } manage_release_fence()82 void manage_release_fence() { 83 release_fence_.Set(release_fence_raw_); 84 release_fence_raw_ = -1; 85 } release_fence_output()86 OutputFd release_fence_output() { 87 return OutputFd(&release_fence_raw_); 88 } 89 display_frame()90 hwc_rect_t display_frame() { 91 return display_frame_; 92 } 93 94 void PopulateDrmLayer(DrmHwcLayer *layer); 95 96 // Layer hooks 97 HWC2::Error SetCursorPosition(int32_t x, int32_t y); 98 HWC2::Error SetLayerBlendMode(int32_t mode); 99 HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence); 100 HWC2::Error SetLayerColor(hwc_color_t color); 101 HWC2::Error SetLayerCompositionType(int32_t type); 102 HWC2::Error SetLayerDataspace(int32_t dataspace); 103 HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame); 104 HWC2::Error SetLayerPlaneAlpha(float alpha); 105 HWC2::Error SetLayerSidebandStream(const native_handle_t *stream); 106 HWC2::Error SetLayerSourceCrop(hwc_frect_t crop); 107 HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage); 108 HWC2::Error SetLayerTransform(int32_t transform); 109 HWC2::Error SetLayerVisibleRegion(hwc_region_t visible); 110 HWC2::Error SetLayerZOrder(uint32_t z); 111 112 private: 113 // sf_type_ stores the initial type given to us by surfaceflinger, 114 // validated_type_ stores the type after running ValidateDisplay 115 HWC2::Composition sf_type_ = HWC2::Composition::Invalid; 116 HWC2::Composition validated_type_ = HWC2::Composition::Invalid; 117 118 HWC2::BlendMode blending_ = HWC2::BlendMode::None; 119 buffer_handle_t buffer_ = NULL; 120 UniqueFd acquire_fence_; 121 int release_fence_raw_ = -1; 122 UniqueFd release_fence_; 123 hwc_rect_t display_frame_; 124 float alpha_ = 1.0f; 125 hwc_frect_t source_crop_; 126 int32_t cursor_x_; 127 int32_t cursor_y_; 128 hwc_color_t layer_color_; 129 HWC2::Transform transform_ = HWC2::Transform::None; 130 uint32_t z_order_ = 0; 131 android_dataspace_t dataspace_ = HAL_DATASPACE_UNKNOWN; 132 }; 133 134 struct HwcCallback { HwcCallbackHwcCallback135 HwcCallback(hwc2_callback_data_t d, hwc2_function_pointer_t f) 136 : data(d), func(f) { 137 } 138 hwc2_callback_data_t data; 139 hwc2_function_pointer_t func; 140 }; 141 142 class HwcDisplay { 143 public: 144 HwcDisplay(ResourceManager *resource_manager, DrmDevice *drm, 145 std::shared_ptr<Importer> importer, hwc2_display_t handle, 146 HWC2::DisplayType type); 147 HwcDisplay(const HwcDisplay &) = delete; 148 HWC2::Error Init(std::vector<DrmPlane *> *planes); 149 150 HWC2::Error RegisterVsyncCallback(hwc2_callback_data_t data, 151 hwc2_function_pointer_t func); 152 void ClearDisplay(); 153 154 std::string Dump(); 155 156 // HWC Hooks 157 HWC2::Error AcceptDisplayChanges(); 158 HWC2::Error CreateLayer(hwc2_layer_t *layer); 159 HWC2::Error DestroyLayer(hwc2_layer_t layer); 160 HWC2::Error GetActiveConfig(hwc2_config_t *config); 161 HWC2::Error GetChangedCompositionTypes(uint32_t *num_elements, 162 hwc2_layer_t *layers, 163 int32_t *types); 164 HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height, 165 int32_t format, int32_t dataspace); 166 HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes); 167 HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute, 168 int32_t *value); 169 HWC2::Error GetDisplayConfigs(uint32_t *num_configs, 170 hwc2_config_t *configs); 171 HWC2::Error GetDisplayName(uint32_t *size, char *name); 172 HWC2::Error GetDisplayRequests(int32_t *display_requests, 173 uint32_t *num_elements, hwc2_layer_t *layers, 174 int32_t *layer_requests); 175 HWC2::Error GetDisplayType(int32_t *type); 176 HWC2::Error GetDozeSupport(int32_t *support); 177 HWC2::Error GetHdrCapabilities(uint32_t *num_types, int32_t *types, 178 float *max_luminance, 179 float *max_average_luminance, 180 float *min_luminance); 181 HWC2::Error GetReleaseFences(uint32_t *num_elements, hwc2_layer_t *layers, 182 int32_t *fences); 183 HWC2::Error PresentDisplay(int32_t *present_fence); 184 HWC2::Error SetActiveConfig(hwc2_config_t config); 185 HWC2::Error ChosePreferredConfig(); 186 HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence, 187 int32_t dataspace, hwc_region_t damage); 188 HWC2::Error SetColorMode(int32_t mode); 189 HWC2::Error SetColorTransform(const float *matrix, int32_t hint); 190 HWC2::Error SetOutputBuffer(buffer_handle_t buffer, int32_t release_fence); 191 HWC2::Error SetPowerMode(int32_t mode); 192 HWC2::Error SetVsyncEnabled(int32_t enabled); 193 HWC2::Error ValidateDisplay(uint32_t *num_types, uint32_t *num_requests); get_layer(hwc2_layer_t layer)194 HwcLayer *get_layer(hwc2_layer_t layer) { 195 auto it = layers_.find(layer); 196 if (it == layers_.end()) 197 return nullptr; 198 return &it->second; 199 } 200 201 private: 202 HWC2::Error CreateComposition(bool test); 203 void AddFenceToPresentFence(int fd); 204 bool HardwareSupportsLayerType(HWC2::Composition comp_type); 205 uint32_t CalcPixOps(std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map, 206 size_t first_z, size_t size); 207 void MarkValidated(std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map, 208 size_t client_first_z, size_t client_size); 209 210 constexpr static size_t MATRIX_SIZE = 16; 211 212 ResourceManager *resource_manager_; 213 DrmDevice *drm_; 214 DrmDisplayCompositor compositor_; 215 std::shared_ptr<Importer> importer_; 216 std::unique_ptr<Planner> planner_; 217 218 std::vector<DrmPlane *> primary_planes_; 219 std::vector<DrmPlane *> overlay_planes_; 220 221 VSyncWorker vsync_worker_; 222 DrmConnector *connector_ = NULL; 223 DrmCrtc *crtc_ = NULL; 224 hwc2_display_t handle_; 225 HWC2::DisplayType type_; 226 uint32_t layer_idx_ = 0; 227 std::map<hwc2_layer_t, HwcLayer> layers_; 228 HwcLayer client_layer_; 229 UniqueFd present_fence_; 230 int32_t color_mode_; 231 std::array<float, MATRIX_SIZE> color_transform_matrix_; 232 android_color_transform_t color_transform_hint_; 233 234 uint32_t frame_no_ = 0; 235 /* Statistics */ 236 struct Stats { minusStats237 Stats minus(Stats b) { 238 return {total_frames_ - b.total_frames_, 239 total_pixops_ - b.total_pixops_, gpu_pixops_ - b.gpu_pixops_, 240 failed_kms_validate_ - b.failed_kms_validate_, 241 failed_kms_present_ - b.failed_kms_present_}; 242 } 243 244 uint32_t total_frames_ = 0; 245 uint64_t total_pixops_ = 0; 246 uint64_t gpu_pixops_ = 0; 247 uint32_t failed_kms_validate_ = 0; 248 uint32_t failed_kms_present_ = 0; 249 } total_stats_, prev_stats_; 250 std::string DumpDelta(DrmHwcTwo::HwcDisplay::Stats delta); 251 }; 252 253 class DrmHotplugHandler : public DrmEventHandler { 254 public: DrmHotplugHandler(DrmHwcTwo * hwc2,DrmDevice * drm)255 DrmHotplugHandler(DrmHwcTwo *hwc2, DrmDevice *drm) 256 : hwc2_(hwc2), drm_(drm) { 257 } 258 void HandleEvent(uint64_t timestamp_us); 259 260 private: 261 DrmHwcTwo *hwc2_; 262 DrmDevice *drm_; 263 }; 264 toDrmHwcTwo(hwc2_device_t * dev)265 static DrmHwcTwo *toDrmHwcTwo(hwc2_device_t *dev) { 266 return static_cast<DrmHwcTwo *>(dev); 267 } 268 269 template <typename PFN, typename T> ToHook(T function)270 static hwc2_function_pointer_t ToHook(T function) { 271 static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer"); 272 return reinterpret_cast<hwc2_function_pointer_t>(function); 273 } 274 275 template <typename T, typename HookType, HookType func, typename... Args> DeviceHook(hwc2_device_t * dev,Args...args)276 static T DeviceHook(hwc2_device_t *dev, Args... args) { 277 DrmHwcTwo *hwc = toDrmHwcTwo(dev); 278 return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...)); 279 } 280 GetDisplay(DrmHwcTwo * hwc,hwc2_display_t display_handle)281 static HwcDisplay *GetDisplay(DrmHwcTwo *hwc, hwc2_display_t display_handle) { 282 auto it = hwc->displays_.find(display_handle); 283 if (it == hwc->displays_.end()) 284 return nullptr; 285 286 return &it->second; 287 } 288 289 template <typename HookType, HookType func, typename... Args> DisplayHook(hwc2_device_t * dev,hwc2_display_t display_handle,Args...args)290 static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle, 291 Args... args) { 292 HwcDisplay *display = GetDisplay(toDrmHwcTwo(dev), display_handle); 293 if (!display) 294 return static_cast<int32_t>(HWC2::Error::BadDisplay); 295 296 return static_cast<int32_t>((display->*func)(std::forward<Args>(args)...)); 297 } 298 299 template <typename HookType, HookType func, typename... Args> LayerHook(hwc2_device_t * dev,hwc2_display_t display_handle,hwc2_layer_t layer_handle,Args...args)300 static int32_t LayerHook(hwc2_device_t *dev, hwc2_display_t display_handle, 301 hwc2_layer_t layer_handle, Args... args) { 302 HwcDisplay *display = GetDisplay(toDrmHwcTwo(dev), display_handle); 303 if (!display) 304 return static_cast<int32_t>(HWC2::Error::BadDisplay); 305 306 HwcLayer *layer = display->get_layer(layer_handle); 307 if (!layer) 308 return static_cast<int32_t>(HWC2::Error::BadLayer); 309 310 return static_cast<int32_t>((layer->*func)(std::forward<Args>(args)...)); 311 } 312 313 // hwc2_device_t hooks 314 static int HookDevClose(hw_device_t *dev); 315 static void HookDevGetCapabilities(hwc2_device_t *dev, uint32_t *out_count, 316 int32_t *out_capabilities); 317 static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device *device, 318 int32_t descriptor); 319 320 // Device functions 321 HWC2::Error CreateVirtualDisplay(uint32_t width, uint32_t height, 322 int32_t *format, hwc2_display_t *display); 323 HWC2::Error DestroyVirtualDisplay(hwc2_display_t display); 324 void Dump(uint32_t *outSize, char *outBuffer); 325 uint32_t GetMaxVirtualDisplayCount(); 326 HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data, 327 hwc2_function_pointer_t function); 328 HWC2::Error CreateDisplay(hwc2_display_t displ, HWC2::DisplayType type); 329 void HandleDisplayHotplug(hwc2_display_t displayid, int state); 330 void HandleInitialHotplugState(DrmDevice *drmDevice); 331 332 ResourceManager resource_manager_; 333 std::map<hwc2_display_t, HwcDisplay> displays_; 334 std::map<HWC2::Callback, HwcCallback> callbacks_; 335 336 std::string mDumpString; 337 }; 338 } // namespace android 339