1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef UI_OZONE_PLATFORM_DRM_HOST_DRM_DISPLAY_HOST_MANAGER_H_ 6 #define UI_OZONE_PLATFORM_DRM_HOST_DRM_DISPLAY_HOST_MANAGER_H_ 7 8 #include <stdint.h> 9 #include <map> 10 #include <memory> 11 12 #include "base/containers/queue.h" 13 #include "base/file_descriptor_posix.h" 14 #include "base/files/scoped_file.h" 15 #include "base/macros.h" 16 #include "base/memory/weak_ptr.h" 17 #include "ui/display/types/native_display_delegate.h" 18 #include "ui/events/ozone/device/device_event.h" 19 #include "ui/events/ozone/device/device_event_observer.h" 20 #include "ui/events/ozone/evdev/event_factory_evdev.h" 21 #include "ui/ozone/platform/drm/host/gpu_thread_observer.h" 22 #include "ui/ozone/public/ozone_platform.h" 23 24 namespace ui { 25 26 class DeviceManager; 27 class DrmDeviceHandle; 28 class DrmDisplayHost; 29 class DrmDisplayHostManager; 30 class DrmNativeDisplayDelegate; 31 class GpuThreadAdapter; 32 33 struct DisplaySnapshot_Params; 34 35 // The portion of the DrmDisplayHostManager implementation that is agnostic 36 // in how its communication with GPU-specific functionality is implemented. 37 // This is used from both the IPC and the in-process versions in MUS. 38 class DrmDisplayHostManager : public DeviceEventObserver, GpuThreadObserver { 39 public: 40 DrmDisplayHostManager( 41 GpuThreadAdapter* proxy, 42 DeviceManager* device_manager, 43 OzonePlatform::InitializedHostProperties* host_properties, 44 InputControllerEvdev* input_controller); 45 ~DrmDisplayHostManager() override; 46 47 DrmDisplayHost* GetDisplay(int64_t display_id); 48 49 // External API. 50 void AddDelegate(DrmNativeDisplayDelegate* delegate); 51 void RemoveDelegate(DrmNativeDisplayDelegate* delegate); 52 void TakeDisplayControl(display::DisplayControlCallback callback); 53 void RelinquishDisplayControl(display::DisplayControlCallback callback); 54 void UpdateDisplays(display::GetDisplaysCallback callback); 55 56 // DeviceEventObserver overrides: 57 void OnDeviceEvent(const DeviceEvent& event) override; 58 59 // GpuThreadObserver overrides: 60 void OnGpuProcessLaunched() override; 61 void OnGpuThreadReady() override; 62 void OnGpuThreadRetired() override; 63 64 // Communication-free implementations of actions performed in response to 65 // messages from the GPU thread. 66 void GpuHasUpdatedNativeDisplays( 67 const std::vector<DisplaySnapshot_Params>& displays); 68 void GpuConfiguredDisplay(int64_t display_id, bool status); 69 void GpuReceivedHDCPState(int64_t display_id, 70 bool status, 71 display::HDCPState state); 72 void GpuUpdatedHDCPState(int64_t display_id, bool status); 73 void GpuTookDisplayControl(bool status); 74 void GpuRelinquishedDisplayControl(bool status); 75 76 private: 77 struct DisplayEvent { DisplayEventDisplayEvent78 DisplayEvent(DeviceEvent::ActionType action_type, 79 const base::FilePath& path) 80 : action_type(action_type), path(path) {} 81 82 DeviceEvent::ActionType action_type; 83 base::FilePath path; 84 }; 85 86 // Handle hotplug events sequentially. 87 void ProcessEvent(); 88 89 // Called as a result of finishing to process the display hotplug event. These 90 // are responsible for dequing the event and scheduling the next event. 91 void OnAddGraphicsDevice(const base::FilePath& path, 92 const base::FilePath& sysfs_path, 93 std::unique_ptr<DrmDeviceHandle> handle); 94 void OnUpdateGraphicsDevice(); 95 void OnRemoveGraphicsDevice(const base::FilePath& path); 96 97 void RunUpdateDisplaysCallback(display::GetDisplaysCallback callback) const; 98 99 void NotifyDisplayDelegate() const; 100 101 GpuThreadAdapter* const proxy_; // Not owned. 102 DeviceManager* const device_manager_; // Not owned. 103 InputControllerEvdev* const input_controller_; // Not owned. 104 105 DrmNativeDisplayDelegate* delegate_ = nullptr; // Not owned. 106 107 // File path for the primary graphics card which is opened by default in the 108 // GPU process. We'll avoid opening this in hotplug events since it will race 109 // with the GPU process trying to open it and aquire DRM master. 110 const base::FilePath primary_graphics_card_path_; 111 112 // Keeps track if there is a dummy display. This happens on initialization 113 // when there is no connection to the GPU to update the displays. 114 bool has_dummy_display_ = false; 115 116 std::vector<std::unique_ptr<DrmDisplayHost>> displays_; 117 118 display::GetDisplaysCallback get_displays_callback_; 119 120 bool display_externally_controlled_ = false; 121 bool display_control_change_pending_ = false; 122 display::DisplayControlCallback take_display_control_callback_; 123 display::DisplayControlCallback relinquish_display_control_callback_; 124 125 // Used to serialize display event processing. This is done since 126 // opening/closing DRM devices cannot be done on the UI thread and are handled 127 // on a worker thread. Thus, we need to queue events in order to process them 128 // in the correct order. 129 base::queue<DisplayEvent> event_queue_; 130 131 // True if a display event is currently being processed on a worker thread. 132 bool task_pending_ = false; 133 134 // Keeps track of all the active DRM devices. The key is the device path, the 135 // value is the sysfs path which has been resolved from the device path. 136 std::map<base::FilePath, base::FilePath> drm_devices_; 137 138 // This is used to cache the primary DRM device until the channel is 139 // established. 140 std::unique_ptr<DrmDeviceHandle> primary_drm_device_handle_; 141 142 base::WeakPtrFactory<DrmDisplayHostManager> weak_ptr_factory_{this}; 143 144 DISALLOW_COPY_AND_ASSIGN(DrmDisplayHostManager); 145 }; 146 147 } // namespace ui 148 149 #endif // UI_OZONE_PLATFORM_DRM_HOST_DRM_DISPLAY_HOST_MANAGER_H_ 150