1 // Copyright 2015 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_GPU_DRM_THREAD_H_ 6 #define UI_OZONE_PLATFORM_DRM_GPU_DRM_THREAD_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 12 #include "base/files/file.h" 13 #include "base/files/scoped_file.h" 14 #include "base/macros.h" 15 #include "base/memory/weak_ptr.h" 16 #include "base/threading/thread.h" 17 #include "mojo/public/cpp/bindings/associated_receiver_set.h" 18 #include "mojo/public/cpp/bindings/pending_associated_receiver.h" 19 #include "mojo/public/cpp/bindings/pending_receiver.h" 20 #include "mojo/public/cpp/bindings/receiver_set.h" 21 #include "ui/display/types/display_configuration_params.h" 22 #include "ui/gfx/native_pixmap_handle.h" 23 #include "ui/gfx/native_widget_types.h" 24 #include "ui/gfx/vsync_provider.h" 25 #include "ui/ozone/platform/drm/common/display_types.h" 26 #include "ui/ozone/platform/drm/gpu/drm_device_generator.h" 27 #include "ui/ozone/public/mojom/device_cursor.mojom.h" 28 #include "ui/ozone/public/mojom/drm_device.mojom.h" 29 #include "ui/ozone/public/overlay_surface_candidate.h" 30 #include "ui/ozone/public/swap_completion_callback.h" 31 32 namespace base { 33 class FilePath; 34 } 35 36 namespace display { 37 struct GammaRampRGBEntry; 38 } // namespace display 39 40 namespace gfx { 41 class Point; 42 class Rect; 43 } // namespace gfx 44 45 namespace ui { 46 47 class DrmDeviceManager; 48 class DrmFramebuffer; 49 class DrmGpuDisplayManager; 50 class GbmBuffer; 51 class ScreenManager; 52 53 struct DrmOverlayPlane; 54 55 // Holds all the DRM related state and performs all DRM related operations. 56 // 57 // The DRM thread is used to insulate DRM operations from potential blocking 58 // behaviour on the GPU main thread in order to reduce the potential for jank 59 // (for example jank in the cursor if the GPU main thread is performing heavy 60 // operations). The inverse is also true as blocking operations on the DRM 61 // thread (such as modesetting) no longer block the GPU main thread. 62 class DrmThread : public base::Thread, 63 public ozone::mojom::DeviceCursor, 64 public ozone::mojom::DrmDevice { 65 public: 66 using OverlayCapabilitiesCallback = 67 base::OnceCallback<void(gfx::AcceleratedWidget, 68 const std::vector<OverlaySurfaceCandidate>&, 69 const std::vector<OverlayStatus>&)>; 70 71 DrmThread(); 72 ~DrmThread() override; 73 74 void Start(base::OnceClosure receiver_completer, 75 std::unique_ptr<DrmDeviceGenerator> device_generator); 76 77 // Runs |task| once a DrmDevice is registered. |done| 78 // will be signaled if it's not null. 79 void RunTaskAfterDeviceReady(base::OnceClosure task, 80 base::WaitableEvent* done); 81 82 // Must be called on the DRM thread. All methods for use from the GPU thread. 83 // DrmThreadProxy (on GPU)thread) is the client for these methods. 84 void CreateBuffer(gfx::AcceleratedWidget widget, 85 const gfx::Size& size, 86 const gfx::Size& framebuffer_size, 87 gfx::BufferFormat format, 88 gfx::BufferUsage usage, 89 uint32_t flags, 90 std::unique_ptr<GbmBuffer>* buffer, 91 scoped_refptr<DrmFramebuffer>* framebuffer); 92 using CreateBufferAsyncCallback = 93 base::OnceCallback<void(std::unique_ptr<GbmBuffer>, 94 scoped_refptr<DrmFramebuffer>)>; 95 void CreateBufferAsync(gfx::AcceleratedWidget widget, 96 const gfx::Size& size, 97 gfx::BufferFormat format, 98 gfx::BufferUsage usage, 99 uint32_t flags, 100 CreateBufferAsyncCallback callback); 101 void CreateBufferFromHandle(gfx::AcceleratedWidget widget, 102 const gfx::Size& size, 103 gfx::BufferFormat format, 104 gfx::NativePixmapHandle handle, 105 std::unique_ptr<GbmBuffer>* buffer, 106 scoped_refptr<DrmFramebuffer>* framebuffer); 107 void SetClearOverlayCacheCallback(base::RepeatingClosure callback); 108 void AddDrmDeviceReceiver( 109 mojo::PendingReceiver<ozone::mojom::DrmDevice> receiver); 110 111 void SetColorSpace(gfx::AcceleratedWidget widget, 112 const gfx::ColorSpace& color_space); 113 114 // Verifies if the display controller can successfully scanout the given set 115 // of OverlaySurfaceCandidates and return the status associated with each 116 // candidate. 117 void CheckOverlayCapabilities( 118 gfx::AcceleratedWidget widget, 119 const std::vector<OverlaySurfaceCandidate>& candidates, 120 OverlayCapabilitiesCallback callback); 121 122 // Similar to CheckOverlayCapabilities() but stores the result in |result| 123 // instead of running a callback. 124 void CheckOverlayCapabilitiesSync( 125 gfx::AcceleratedWidget widget, 126 const std::vector<OverlaySurfaceCandidate>& candidates, 127 std::vector<OverlayStatus>* result); 128 129 // DrmWindowProxy (on GPU thread) is the client for these methods. 130 void SchedulePageFlip(gfx::AcceleratedWidget widget, 131 std::vector<DrmOverlayPlane> planes, 132 SwapCompletionOnceCallback submission_callback, 133 PresentationOnceCallback presentation_callback); 134 135 void IsDeviceAtomic(gfx::AcceleratedWidget widget, bool* is_atomic); 136 137 // ozone::mojom::DrmDevice 138 void CreateWindow(gfx::AcceleratedWidget widget, 139 const gfx::Rect& initial_bounds) override; 140 void DestroyWindow(gfx::AcceleratedWidget widget) override; 141 void SetWindowBounds(gfx::AcceleratedWidget widget, 142 const gfx::Rect& bounds) override; 143 void TakeDisplayControl(base::OnceCallback<void(bool)> callback) override; 144 void RelinquishDisplayControl( 145 base::OnceCallback<void(bool)> callback) override; 146 void RefreshNativeDisplays( 147 base::OnceCallback<void(MovableDisplaySnapshots)> callback) override; 148 void AddGraphicsDevice(const base::FilePath& path, base::File file) override; 149 void RemoveGraphicsDevice(const base::FilePath& path) override; 150 void ConfigureNativeDisplays( 151 const std::vector<display::DisplayConfigurationParams>& config_requests, 152 ConfigureNativeDisplaysCallback callback) override; 153 void GetHDCPState(int64_t display_id, 154 base::OnceCallback<void(int64_t, 155 bool, 156 display::HDCPState, 157 display::ContentProtectionMethod)> 158 callback) override; 159 void SetHDCPState(int64_t display_id, 160 display::HDCPState state, 161 display::ContentProtectionMethod protection_method, 162 base::OnceCallback<void(int64_t, bool)> callback) override; 163 void SetColorMatrix(int64_t display_id, 164 const std::vector<float>& color_matrix) override; 165 void SetGammaCorrection( 166 int64_t display_id, 167 const std::vector<display::GammaRampRGBEntry>& degamma_lut, 168 const std::vector<display::GammaRampRGBEntry>& gamma_lut) override; 169 void SetPrivacyScreen(int64_t display_id, bool enabled) override; 170 void GetDeviceCursor( 171 mojo::PendingAssociatedReceiver<ozone::mojom::DeviceCursor> receiver) 172 override; 173 174 // ozone::mojom::DeviceCursor 175 void SetCursor(gfx::AcceleratedWidget widget, 176 const std::vector<SkBitmap>& bitmaps, 177 const gfx::Point& location, 178 int32_t frame_delay_ms) override; 179 void MoveCursor(gfx::AcceleratedWidget widget, 180 const gfx::Point& location) override; 181 182 // base::Thread: 183 void Init() override; 184 185 private: 186 struct TaskInfo { 187 base::OnceClosure task; 188 base::WaitableEvent* done; 189 190 TaskInfo(base::OnceClosure task, base::WaitableEvent* done); 191 TaskInfo(TaskInfo&& other); 192 ~TaskInfo(); 193 }; 194 195 void OnPlanesReadyForPageFlip(gfx::AcceleratedWidget widget, 196 SwapCompletionOnceCallback submission_callback, 197 PresentationOnceCallback presentation_callback, 198 std::vector<DrmOverlayPlane> planes); 199 200 // Called when a DrmDevice or DrmWindow is created. Runs tasks that are now 201 // unblocked. 202 void ProcessPendingTasks(); 203 204 std::unique_ptr<DrmDeviceManager> device_manager_; 205 std::unique_ptr<ScreenManager> screen_manager_; 206 std::unique_ptr<DrmGpuDisplayManager> display_manager_; 207 208 base::OnceClosure complete_early_receiver_requests_; 209 210 // The mojo implementation requires an AssociatedReceiverSet because the 211 // DrmThread serves requests from two different client threads. 212 mojo::AssociatedReceiverSet<ozone::mojom::DeviceCursor> cursor_receivers_; 213 214 // This is a ReceiverSet because the regular Receiver causes the sequence 215 // checker in InterfaceEndpointClient to fail during teardown. 216 // TODO(samans): Figure out why. 217 mojo::ReceiverSet<ozone::mojom::DrmDevice> drm_receivers_; 218 219 // The AcceleratedWidget from the last call to CreateWindow. 220 gfx::AcceleratedWidget last_created_window_ = gfx::kNullAcceleratedWidget; 221 222 // The tasks that are blocked on a DrmDevice becoming available. 223 std::vector<TaskInfo> pending_tasks_; 224 225 // Holds the DrmDeviceGenerator that DrmDeviceManager will use. Will be passed 226 // on to DrmDeviceManager after the thread starts. 227 std::unique_ptr<DrmDeviceGenerator> device_generator_; 228 229 base::WeakPtrFactory<DrmThread> weak_ptr_factory_{this}; 230 231 DISALLOW_COPY_AND_ASSIGN(DrmThread); 232 }; 233 234 } // namespace ui 235 236 #endif // UI_OZONE_PLATFORM_DRM_GPU_DRM_THREAD_H_ 237