1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3  */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 
8 #ifndef __MOZ_DMABUF_LIB_WRAPPER_H__
9 #define __MOZ_DMABUF_LIB_WRAPPER_H__
10 
11 #include "mozilla/widget/gbm.h"
12 #include "mozilla/StaticMutex.h"
13 
14 #ifdef MOZ_LOGGING
15 #  include "mozilla/Logging.h"
16 #  include "nsTArray.h"
17 #  include "Units.h"
18 extern mozilla::LazyLogModule gDmabufLog;
19 #  define LOGDMABUF(args) MOZ_LOG(gDmabufLog, mozilla::LogLevel::Debug, args)
20 #else
21 #  define LOGDMABUF(args)
22 #endif /* MOZ_LOGGING */
23 
24 #ifndef DRM_FORMAT_MOD_INVALID
25 #  define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
26 #endif
27 
28 namespace mozilla {
29 namespace widget {
30 
31 typedef struct gbm_device* (*CreateDeviceFunc)(int);
32 typedef struct gbm_bo* (*CreateFunc)(struct gbm_device*, uint32_t, uint32_t,
33                                      uint32_t, uint32_t);
34 typedef struct gbm_bo* (*CreateWithModifiersFunc)(struct gbm_device*, uint32_t,
35                                                   uint32_t, uint32_t,
36                                                   const uint64_t*,
37                                                   const unsigned int);
38 typedef uint64_t (*GetModifierFunc)(struct gbm_bo*);
39 typedef uint32_t (*GetStrideFunc)(struct gbm_bo*);
40 typedef int (*GetFdFunc)(struct gbm_bo*);
41 typedef void (*DestroyFunc)(struct gbm_bo*);
42 typedef void* (*MapFunc)(struct gbm_bo*, uint32_t, uint32_t, uint32_t, uint32_t,
43                          uint32_t, uint32_t*, void**);
44 typedef void (*UnmapFunc)(struct gbm_bo*, void*);
45 typedef int (*GetPlaneCountFunc)(struct gbm_bo*);
46 typedef union gbm_bo_handle (*GetHandleForPlaneFunc)(struct gbm_bo*, int);
47 typedef uint32_t (*GetStrideForPlaneFunc)(struct gbm_bo*, int);
48 typedef uint32_t (*GetOffsetFunc)(struct gbm_bo*, int);
49 typedef int (*DeviceIsFormatSupportedFunc)(struct gbm_device*, uint32_t,
50                                            uint32_t);
51 typedef int (*DrmPrimeHandleToFDFunc)(int, uint32_t, uint32_t, int*);
52 
53 class nsGbmLib {
54  public:
55   static bool Load();
56   static bool IsLoaded();
57   static bool IsAvailable();
58   static bool IsModifierAvailable();
59 
CreateDevice(int fd)60   static struct gbm_device* CreateDevice(int fd) {
61     StaticMutexAutoLock lockDRI(sDRILock);
62     return sCreateDevice(fd);
63   };
Create(struct gbm_device * gbm,uint32_t width,uint32_t height,uint32_t format,uint32_t flags)64   static struct gbm_bo* Create(struct gbm_device* gbm, uint32_t width,
65                                uint32_t height, uint32_t format,
66                                uint32_t flags) {
67     StaticMutexAutoLock lockDRI(sDRILock);
68     return sCreate(gbm, width, height, format, flags);
69   }
Destroy(struct gbm_bo * bo)70   static void Destroy(struct gbm_bo* bo) {
71     StaticMutexAutoLock lockDRI(sDRILock);
72     sDestroy(bo);
73   }
GetStride(struct gbm_bo * bo)74   static uint32_t GetStride(struct gbm_bo* bo) {
75     StaticMutexAutoLock lockDRI(sDRILock);
76     return sGetStride(bo);
77   }
GetFd(struct gbm_bo * bo)78   static int GetFd(struct gbm_bo* bo) {
79     StaticMutexAutoLock lockDRI(sDRILock);
80     return sGetFd(bo);
81   }
Map(struct gbm_bo * bo,uint32_t x,uint32_t y,uint32_t width,uint32_t height,uint32_t flags,uint32_t * stride,void ** map_data)82   static void* Map(struct gbm_bo* bo, uint32_t x, uint32_t y, uint32_t width,
83                    uint32_t height, uint32_t flags, uint32_t* stride,
84                    void** map_data) {
85     StaticMutexAutoLock lockDRI(sDRILock);
86     return sMap(bo, x, y, width, height, flags, stride, map_data);
87   }
Unmap(struct gbm_bo * bo,void * map_data)88   static void Unmap(struct gbm_bo* bo, void* map_data) {
89     StaticMutexAutoLock lockDRI(sDRILock);
90     sUnmap(bo, map_data);
91   }
CreateWithModifiers(struct gbm_device * gbm,uint32_t width,uint32_t height,uint32_t format,const uint64_t * modifiers,const unsigned int count)92   static struct gbm_bo* CreateWithModifiers(struct gbm_device* gbm,
93                                             uint32_t width, uint32_t height,
94                                             uint32_t format,
95                                             const uint64_t* modifiers,
96                                             const unsigned int count) {
97     StaticMutexAutoLock lockDRI(sDRILock);
98     return sCreateWithModifiers(gbm, width, height, format, modifiers, count);
99   }
GetModifier(struct gbm_bo * bo)100   static uint64_t GetModifier(struct gbm_bo* bo) {
101     StaticMutexAutoLock lockDRI(sDRILock);
102     return sGetModifier(bo);
103   }
GetPlaneCount(struct gbm_bo * bo)104   static int GetPlaneCount(struct gbm_bo* bo) {
105     StaticMutexAutoLock lockDRI(sDRILock);
106     return sGetPlaneCount(bo);
107   }
GetHandleForPlane(struct gbm_bo * bo,int plane)108   static union gbm_bo_handle GetHandleForPlane(struct gbm_bo* bo, int plane) {
109     StaticMutexAutoLock lockDRI(sDRILock);
110     return sGetHandleForPlane(bo, plane);
111   }
GetStrideForPlane(struct gbm_bo * bo,int plane)112   static uint32_t GetStrideForPlane(struct gbm_bo* bo, int plane) {
113     StaticMutexAutoLock lockDRI(sDRILock);
114     return sGetStrideForPlane(bo, plane);
115   }
GetOffset(struct gbm_bo * bo,int plane)116   static uint32_t GetOffset(struct gbm_bo* bo, int plane) {
117     StaticMutexAutoLock lockDRI(sDRILock);
118     return sGetOffset(bo, plane);
119   }
DeviceIsFormatSupported(struct gbm_device * gbm,uint32_t format,uint32_t usage)120   static int DeviceIsFormatSupported(struct gbm_device* gbm, uint32_t format,
121                                      uint32_t usage) {
122     StaticMutexAutoLock lockDRI(sDRILock);
123     return sDeviceIsFormatSupported(gbm, format, usage);
124   }
DrmPrimeHandleToFD(int fd,uint32_t handle,uint32_t flags,int * prime_fd)125   static int DrmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags,
126                                 int* prime_fd) {
127     StaticMutexAutoLock lockDRI(sDRILock);
128     return sDrmPrimeHandleToFD(fd, handle, flags, prime_fd);
129   }
130 
131  private:
132   static CreateDeviceFunc sCreateDevice;
133   static CreateFunc sCreate;
134   static CreateWithModifiersFunc sCreateWithModifiers;
135   static GetModifierFunc sGetModifier;
136   static GetStrideFunc sGetStride;
137   static GetFdFunc sGetFd;
138   static DestroyFunc sDestroy;
139   static MapFunc sMap;
140   static UnmapFunc sUnmap;
141   static GetPlaneCountFunc sGetPlaneCount;
142   static GetHandleForPlaneFunc sGetHandleForPlane;
143   static GetStrideForPlaneFunc sGetStrideForPlane;
144   static GetOffsetFunc sGetOffset;
145   static DeviceIsFormatSupportedFunc sDeviceIsFormatSupported;
146   static DrmPrimeHandleToFDFunc sDrmPrimeHandleToFD;
147 
148   static void* sGbmLibHandle;
149   static void* sXf86DrmLibHandle;
150   static mozilla::StaticMutex sDRILock;
151   static bool sLibLoaded;
152 };
153 
154 struct GbmFormat {
155   bool mIsSupported;
156   bool mHasAlpha;
157   int mFormat;
158   uint64_t* mModifiers;
159   int mModifiersCount;
160 };
161 
162 class nsDMABufDevice {
163  public:
164   nsDMABufDevice();
165 
166   gbm_device* GetGbmDevice();
167   // Returns -1 if we fails to gbm device file descriptor.
168   int GetGbmDeviceFd();
169 
170   // Use dmabuf for WebRender general web content
171   bool IsDMABufTexturesEnabled();
172   // Use dmabuf for video playback
173   bool IsDMABufVideoEnabled();
174   // Use dmabuf for VA-API video playback
175   bool IsDMABufVAAPIEnabled();
176   // Use dmabuf for WebGL content
177   bool IsDMABufWebGLEnabled();
178 
179   GbmFormat* GetGbmFormat(bool aHasAlpha);
180   GbmFormat* GetExactGbmFormat(int aFormat);
181   void ResetFormatsModifiers();
182   void AddFormatModifier(bool aHasAlpha, int aFormat, uint32_t mModifierHi,
183                          uint32_t mModifierLo);
184   bool Configure(nsACString& aFailureId);
185 
186  private:
187   bool IsDMABufEnabled();
188 
189   GbmFormat mXRGBFormat;
190   GbmFormat mARGBFormat;
191 
192   gbm_device* mGbmDevice;
193   int mGbmFd;
194   bool mInitialized;
195 };
196 
197 nsDMABufDevice* GetDMABufDevice();
198 
199 }  // namespace widget
200 }  // namespace mozilla
201 
202 #endif  // __MOZ_DMABUF_LIB_WRAPPER_H__
203