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_GPU_DRM_DEVICE_H_
6 #define UI_OZONE_PLATFORM_DRM_GPU_DRM_DEVICE_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <memory>
11 #include <vector>
12 
13 #include "base/callback.h"
14 #include "base/files/file.h"
15 #include "base/files/file_path.h"
16 #include "base/macros.h"
17 #include "base/memory/ref_counted.h"
18 #include "base/time/time.h"
19 #include "ui/gfx/geometry/rect.h"
20 #include "ui/gfx/geometry/rect_f.h"
21 #include "ui/gfx/linux/gbm_device.h"
22 #include "ui/gfx/overlay_transform.h"
23 #include "ui/ozone/platform/drm/common/scoped_drm_types.h"
24 #include "ui/ozone/platform/drm/gpu/page_flip_request.h"
25 
26 typedef struct _drmEventContext drmEventContext;
27 typedef struct _drmModeModeInfo drmModeModeInfo;
28 
29 struct SkImageInfo;
30 
31 namespace display {
32 struct GammaRampRGBEntry;
33 }
34 
35 namespace ui {
36 
37 class HardwareDisplayPlaneManager;
38 class DrmDevice;
39 
40 class DrmPropertyBlobMetadata {
41  public:
42   DrmPropertyBlobMetadata(DrmDevice* drm, uint32_t id);
43   ~DrmPropertyBlobMetadata();
44 
id()45   uint32_t id() const { return id_; }
46 
47  private:
48   DrmDevice* drm_;  // Not owned;
49   uint32_t id_;
50 
51   DISALLOW_COPY_AND_ASSIGN(DrmPropertyBlobMetadata);
52 };
53 
54 using ScopedDrmPropertyBlob = std::unique_ptr<DrmPropertyBlobMetadata>;
55 
56 // Wraps DRM calls into a nice interface. Used to provide different
57 // implementations of the DRM calls. For the actual implementation the DRM API
58 // would be called. In unit tests this interface would be stubbed.
59 class DrmDevice : public base::RefCountedThreadSafe<DrmDevice> {
60  public:
61   using PageFlipCallback =
62       base::OnceCallback<void(unsigned int /* frame */,
63                               base::TimeTicks /* timestamp */)>;
64 
65   struct Property {
66     // Unique identifier for the property. 0 denotes an invalid ID.
67     uint32_t id;
68 
69     // Depending on the property, this may be an actual value describing the
70     // property or an ID of another property.
71     uint64_t value;
72   };
73 
74   DrmDevice(const base::FilePath& device_path,
75             base::File file,
76             bool is_primary_device,
77             std::unique_ptr<GbmDevice> gbm_device);
78 
is_primary_device()79   bool is_primary_device() const { return is_primary_device_; }
80 
is_atomic()81   bool is_atomic() const { return is_atomic_; }
82 
allow_addfb2_modifiers()83   bool allow_addfb2_modifiers() const { return allow_addfb2_modifiers_; }
84 
85   // Open device.
86   virtual bool Initialize();
87 
88   // Returns all the DRM resources for this device. This includes CRTC,
89   // connectors, and encoders state.
90   virtual ScopedDrmResourcesPtr GetResources();
91 
92   // Returns the properties associated with object with id |object_id| and type
93   // |object_type|. |object_type| is one of DRM_MODE_OBJECT_*.
94   virtual ScopedDrmObjectPropertyPtr GetObjectProperties(uint32_t object_id,
95                                                          uint32_t object_type);
96 
97   // Get the CRTC state. This is generally used to save state before using the
98   // CRTC. When the user finishes using the CRTC, the user should restore the
99   // CRTC to it's initial state. Use |SetCrtc| to restore the state.
100   virtual ScopedDrmCrtcPtr GetCrtc(uint32_t crtc_id);
101 
102   // Used to configure CRTC with ID |crtc_id| to use the connector in
103   // |connectors|. The CRTC will be configured with mode |mode| and will display
104   // the framebuffer with ID |framebuffer|. Before being able to display the
105   // framebuffer, it should be registered with the CRTC using |AddFramebuffer|.
106   virtual bool SetCrtc(uint32_t crtc_id,
107                        uint32_t framebuffer,
108                        std::vector<uint32_t> connectors,
109                        const drmModeModeInfo& mode);
110 
111   virtual bool DisableCrtc(uint32_t crtc_id);
112 
113   // Returns the connector properties for |connector_id|.
114   virtual ScopedDrmConnectorPtr GetConnector(uint32_t connector_id);
115 
116   // Register any format buffer with the CRTC. On successful registration, the
117   // CRTC will assign a framebuffer ID to |framebuffer|.
118   virtual bool AddFramebuffer2(uint32_t width,
119                                uint32_t height,
120                                uint32_t format,
121                                uint32_t handles[4],
122                                uint32_t strides[4],
123                                uint32_t offsets[4],
124                                uint64_t modifiers[4],
125                                uint32_t* framebuffer,
126                                uint32_t flags);
127 
128   // Deregister the given |framebuffer|.
129   virtual bool RemoveFramebuffer(uint32_t framebuffer);
130 
131   // Get the DRM details associated with |framebuffer|.
132   virtual ScopedDrmFramebufferPtr GetFramebuffer(uint32_t framebuffer);
133 
134   // Schedules a pageflip for CRTC |crtc_id|. This function will return
135   // immediately. Upon completion of the pageflip event, the CRTC will be
136   // displaying the buffer with ID |framebuffer| and will have a DRM event
137   // queued on |fd_|.
138   //
139   // On success, true is returned and |page_flip_request| will receive a
140   // callback signalling completion of the flip.
141   virtual bool PageFlip(uint32_t crtc_id,
142                         uint32_t framebuffer,
143                         scoped_refptr<PageFlipRequest> page_flip_request);
144 
145   // Returns the list of all planes available on this DRM device.
146   virtual ScopedDrmPlaneResPtr GetPlaneResources();
147 
148   // Returns the properties associated with plane with id |plane_id|.
149   virtual ScopedDrmPlanePtr GetPlane(uint32_t plane_id);
150 
151   // Returns the property with name |name| associated with |connector|. Returns
152   // NULL if property not found. If the returned value is valid, it must be
153   // released using FreeProperty().
154   virtual ScopedDrmPropertyPtr GetProperty(drmModeConnector* connector,
155                                            const char* name);
156 
157   virtual ScopedDrmPropertyPtr GetProperty(uint32_t id);
158 
159   // Sets the value of property with ID |property_id| to |value|. The property
160   // is applied to the connector with ID |connector_id|.
161   virtual bool SetProperty(uint32_t connector_id,
162                            uint32_t property_id,
163                            uint64_t value);
164 
165   // Creates a property blob with data |blob| of size |size|.
166   virtual ScopedDrmPropertyBlob CreatePropertyBlob(const void* blob,
167                                                    size_t size);
168 
169   virtual void DestroyPropertyBlob(uint32_t id);
170 
171   // Returns a binary blob associated with |property_id|. May be nullptr if the
172   // property couldn't be found.
173   virtual ScopedDrmPropertyBlobPtr GetPropertyBlob(uint32_t property_id);
174 
175   // Returns a binary blob associated with |connector|. The binary blob is
176   // associated with the property with name |name|. Return NULL if the property
177   // could not be found or if the property does not have a binary blob. If valid
178   // the returned object must be freed using FreePropertyBlob().
179   virtual ScopedDrmPropertyBlobPtr GetPropertyBlob(drmModeConnector* connector,
180                                                    const char* name);
181 
182   // Sets a property (defined by {|property_id|, |property_value|} on an object
183   // with ID |object_id| and type |object_type|.
184   // |object_id| and |property_id| are unique identifiers.
185   // |object_type| is one of DRM_MODE_OBJECT_*.
186   virtual bool SetObjectProperty(uint32_t object_id,
187                                  uint32_t object_type,
188                                  uint32_t property_id,
189                                  uint32_t property_value);
190 
191   // Can be used to query device/driver |capability|. Sets the value of
192   // |capability| to |value|. Returns true in case of a succesful query.
193   virtual bool GetCapability(uint64_t capability, uint64_t* value);
194 
195   // Set the cursor to be displayed in CRTC |crtc_id|. (width, height) is the
196   // cursor size pointed by |handle|.
197   virtual bool SetCursor(uint32_t crtc_id,
198                          uint32_t handle,
199                          const gfx::Size& size);
200 
201   // Move the cursor on CRTC |crtc_id| to (x, y);
202   virtual bool MoveCursor(uint32_t crtc_id, const gfx::Point& point);
203 
204   virtual bool CreateDumbBuffer(const SkImageInfo& info,
205                                 uint32_t* handle,
206                                 uint32_t* stride);
207 
208   virtual bool DestroyDumbBuffer(uint32_t handle);
209 
210   virtual bool MapDumbBuffer(uint32_t handle, size_t size, void** pixels);
211 
212   virtual bool UnmapDumbBuffer(void* pixels, size_t size);
213 
214   virtual bool CloseBufferHandle(uint32_t handle);
215 
216   // On success, true is returned and |page_flip_request| will receive a
217   // callback signalling completion of the flip, if provided.
218   virtual bool CommitProperties(
219       drmModeAtomicReq* properties,
220       uint32_t flags,
221       uint32_t crtc_count,
222       scoped_refptr<PageFlipRequest> page_flip_request);
223 
224   virtual bool SetCapability(uint64_t capability, uint64_t value);
225 
226   virtual bool SetGammaRamp(uint32_t crtc_id,
227                             const std::vector<display::GammaRampRGBEntry>& lut);
228 
229   // Drm master related
230   virtual bool SetMaster();
231   virtual bool DropMaster();
232 
get_fd()233   int get_fd() const { return file_.GetPlatformFile(); }
234 
device_path()235   base::FilePath device_path() const { return device_path_; }
236 
plane_manager()237   HardwareDisplayPlaneManager* plane_manager() { return plane_manager_.get(); }
238 
gbm_device()239   GbmDevice* gbm_device() const { return gbm_.get(); }
240 
241  protected:
242   friend class base::RefCountedThreadSafe<DrmDevice>;
243 
244   virtual ~DrmDevice();
245 
246   std::unique_ptr<HardwareDisplayPlaneManager> plane_manager_;
247 
248  private:
249   class IOWatcher;
250   class PageFlipManager;
251 
252   // Path to the DRM device (in sysfs).
253   const base::FilePath device_path_;
254 
255   // DRM device.
256   const base::File file_;
257 
258   std::unique_ptr<PageFlipManager> page_flip_manager_;
259 
260   // Watcher for |fd_| listening for page flip events.
261   std::unique_ptr<IOWatcher> watcher_;
262 
263   const bool is_primary_device_;
264 
265   bool is_atomic_ = false;
266 
267   bool allow_addfb2_modifiers_ = false;
268 
269   const std::unique_ptr<GbmDevice> gbm_;
270 
271   DISALLOW_COPY_AND_ASSIGN(DrmDevice);
272 };
273 
274 }  // namespace ui
275 
276 #endif  // UI_OZONE_PLATFORM_DRM_GPU_DRM_DEVICE_H_
277