1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef DMABufSurface_h__
8 #define DMABufSurface_h__
11 #include "mozilla/widget/nsWaylandDisplay.h"
12 #include "mozilla/widget/va_drmcommon.h"
15 typedef void* EGLImageKHR
;
16 typedef void* EGLSyncKHR
;
18 #define DMABUF_BUFFER_PLANES 4
20 #ifndef VA_FOURCC_NV12
21 # define VA_FOURCC_NV12 0x3231564E
23 #ifndef VA_FOURCC_YV12
24 # define VA_FOURCC_YV12 0x32315659
26 #ifndef VA_FOURCC_P010
27 # define VA_FOURCC_P010 0x30313050
35 class SurfaceDescriptor
;
36 class SurfaceDescriptorDMABuf
;
41 } // namespace mozilla
44 // Use alpha pixel format
45 DMABUF_ALPHA
= 1 << 0,
46 // Surface is used as texture and may be also shared
47 DMABUF_TEXTURE
= 1 << 1,
48 // Use modifiers. Such dmabuf surface may have more planes
49 // and complex internal structure (tiling/compression/etc.)
50 // so we can't do direct rendering to it.
51 DMABUF_USE_MODIFIERS
= 1 << 3,
54 class DMABufSurfaceRGBA
;
55 class DMABufSurfaceYUV
;
59 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DMABufSurface
)
67 // Import surface from SurfaceDescriptor. This is usually
68 // used to copy surface from another process over IPC.
69 // When a global reference counter was created for the surface
70 // (see bellow) it's automatically referenced.
71 static already_AddRefed
<DMABufSurface
> CreateDMABufSurface(
72 const mozilla::layers::SurfaceDescriptor
& aDesc
);
74 // Export surface to another process via. SurfaceDescriptor.
75 virtual bool Serialize(
76 mozilla::layers::SurfaceDescriptor
& aOutDescriptor
) = 0;
78 virtual int GetWidth(int aPlane
= 0) = 0;
79 virtual int GetHeight(int aPlane
= 0) = 0;
80 virtual mozilla::gfx::SurfaceFormat
GetFormat() = 0;
81 virtual mozilla::gfx::SurfaceFormat
GetFormatGL() = 0;
83 virtual bool CreateTexture(mozilla::gl::GLContext
* aGLContext
,
85 virtual void ReleaseTextures() = 0;
86 virtual GLuint
GetTexture(int aPlane
= 0) = 0;
87 virtual EGLImageKHR
GetEGLImage(int aPlane
= 0) = 0;
89 SurfaceType
GetSurfaceType() { return mSurfaceType
; };
90 virtual int GetTextureCount() = 0;
92 bool IsMapped(int aPlane
= 0) { return (mMappedRegion
[aPlane
] != nullptr); };
93 void Unmap(int aPlane
= 0);
95 virtual DMABufSurfaceRGBA
* GetAsDMABufSurfaceRGBA() { return nullptr; }
96 virtual DMABufSurfaceYUV
* GetAsDMABufSurfaceYUV() { return nullptr; }
98 virtual mozilla::gfx::YUVColorSpace
GetYUVColorSpace() {
99 return mozilla::gfx::YUVColorSpace::Default
;
102 bool IsFullRange() { return mColorRange
== mozilla::gfx::ColorRange::FULL
; };
103 void SetColorRange(mozilla::gfx::ColorRange aColorRange
) {
104 mColorRange
= aColorRange
;
111 // Set and get a global surface UID. The UID is shared across process
112 // and it's used to track surface lifetime in various parts of rendering
114 uint32_t GetUID() const { return mUID
; };
116 // Creates a global reference counter objects attached to the surface.
117 // It's created as unreferenced, i.e. IsGlobalRefSet() returns false
118 // right after GlobalRefCountCreate() call.
120 // The counter is shared by all surface instances across processes
121 // so it tracks global surface usage.
123 // The counter is automatically referenced when a new surface instance is
124 // created with SurfaceDescriptor (usually copied to another process over IPC)
125 // and it's unreferenced when surface is deleted.
127 // So without any additional GlobalRefAdd()/GlobalRefRelease() calls
128 // the IsGlobalRefSet() returns true if any other process use the surface.
129 void GlobalRefCountCreate();
131 // If global reference counter was created by GlobalRefCountCreate()
132 // returns true when there's an active surface reference.
133 bool IsGlobalRefSet() const;
135 // Add/Remove additional reference to the surface global reference counter.
137 void GlobalRefRelease();
139 // Release all underlying data.
140 virtual void ReleaseSurface() = 0;
143 virtual void DumpToFile(const char* pFile
){};
146 DMABufSurface(SurfaceType aSurfaceType
);
149 virtual bool Create(const mozilla::layers::SurfaceDescriptor
& aDesc
) = 0;
151 void GlobalRefCountImport(int aFd
);
152 void GlobalRefCountDelete();
154 void ReleaseDMABuf();
156 void* MapInternal(uint32_t aX
, uint32_t aY
, uint32_t aWidth
, uint32_t aHeight
,
157 uint32_t* aStride
, int aGbmFlags
, int aPlane
= 0);
159 // We want to keep number of opened file descriptors low so open/close
160 // DMABuf file handles only when we need them, i.e. when DMABuf is exported
161 // to another process or to EGL.
162 virtual bool OpenFileDescriptorForPlane(
163 const mozilla::MutexAutoLock
& aProofOfLock
, int aPlane
) = 0;
164 virtual void CloseFileDescriptorForPlane(
165 const mozilla::MutexAutoLock
& aProofOfLock
, int aPlane
,
166 bool aForceClose
= false) = 0;
167 bool OpenFileDescriptors(const mozilla::MutexAutoLock
& aProofOfLock
);
168 void CloseFileDescriptors(const mozilla::MutexAutoLock
& aProofOfLock
,
169 bool aForceClose
= false);
171 virtual ~DMABufSurface();
173 SurfaceType mSurfaceType
;
174 uint64_t mBufferModifiers
[DMABUF_BUFFER_PLANES
];
176 int mBufferPlaneCount
;
177 int mDmabufFds
[DMABUF_BUFFER_PLANES
];
178 uint32_t mDrmFormats
[DMABUF_BUFFER_PLANES
];
179 uint32_t mStrides
[DMABUF_BUFFER_PLANES
];
180 uint32_t mOffsets
[DMABUF_BUFFER_PLANES
];
182 struct gbm_bo
* mGbmBufferObject
[DMABUF_BUFFER_PLANES
];
183 void* mMappedRegion
[DMABUF_BUFFER_PLANES
];
184 void* mMappedRegionData
[DMABUF_BUFFER_PLANES
];
185 uint32_t mMappedRegionStride
[DMABUF_BUFFER_PLANES
];
189 RefPtr
<mozilla::gl::GLContext
> mGL
;
191 int mGlobalRefCountFd
;
193 mozilla::Mutex mSurfaceLock MOZ_UNANNOTATED
;
195 mozilla::gfx::ColorRange mColorRange
= mozilla::gfx::ColorRange::LIMITED
;
198 class DMABufSurfaceRGBA
: public DMABufSurface
{
200 static already_AddRefed
<DMABufSurfaceRGBA
> CreateDMABufSurface(
201 int aWidth
, int aHeight
, int aDMABufSurfaceFlags
);
203 bool Serialize(mozilla::layers::SurfaceDescriptor
& aOutDescriptor
);
205 DMABufSurfaceRGBA
* GetAsDMABufSurfaceRGBA() { return this; }
209 void ReleaseSurface();
211 bool CopyFrom(class DMABufSurface
* aSourceSurface
);
213 int GetWidth(int aPlane
= 0) { return mWidth
; };
214 int GetHeight(int aPlane
= 0) { return mHeight
; };
215 mozilla::gfx::SurfaceFormat
GetFormat();
216 mozilla::gfx::SurfaceFormat
GetFormatGL();
219 void* MapReadOnly(uint32_t aX
, uint32_t aY
, uint32_t aWidth
, uint32_t aHeight
,
220 uint32_t* aStride
= nullptr);
221 void* MapReadOnly(uint32_t* aStride
= nullptr);
222 void* Map(uint32_t aX
, uint32_t aY
, uint32_t aWidth
, uint32_t aHeight
,
223 uint32_t* aStride
= nullptr);
224 void* Map(uint32_t* aStride
= nullptr);
225 void* GetMappedRegion(int aPlane
= 0) { return mMappedRegion
[aPlane
]; };
226 uint32_t GetMappedRegionStride(int aPlane
= 0) {
227 return mMappedRegionStride
[aPlane
];
230 bool CreateTexture(mozilla::gl::GLContext
* aGLContext
, int aPlane
= 0);
231 void ReleaseTextures();
232 GLuint
GetTexture(int aPlane
= 0) { return mTexture
; };
233 EGLImageKHR
GetEGLImage(int aPlane
= 0) { return mEGLImage
; };
235 bool CreateWlBuffer();
236 void ReleaseWlBuffer();
237 wl_buffer
* GetWlBuffer() { return mWlBuffer
; };
239 int GetTextureCount() { return 1; };
242 virtual void DumpToFile(const char* pFile
);
248 ~DMABufSurfaceRGBA();
250 bool Create(int aWidth
, int aHeight
, int aDMABufSurfaceFlags
);
251 bool Create(const mozilla::layers::SurfaceDescriptor
& aDesc
);
253 bool ImportSurfaceDescriptor(const mozilla::layers::SurfaceDescriptor
& aDesc
);
255 bool OpenFileDescriptorForPlane(const mozilla::MutexAutoLock
& aProofOfLock
,
257 void CloseFileDescriptorForPlane(const mozilla::MutexAutoLock
& aProofOfLock
,
258 int aPlane
, bool aForceClose
);
265 mozilla::widget::GbmFormat
* mGmbFormat
;
267 EGLImageKHR mEGLImage
;
269 uint32_t mGbmBufferFlags
;
270 wl_buffer
* mWlBuffer
;
273 class DMABufSurfaceYUV
: public DMABufSurface
{
275 static already_AddRefed
<DMABufSurfaceYUV
> CreateYUVSurface(
276 int aWidth
, int aHeight
, void** aPixelData
= nullptr,
277 int* aLineSizes
= nullptr);
279 static already_AddRefed
<DMABufSurfaceYUV
> CreateYUVSurface(
280 const VADRMPRIMESurfaceDescriptor
& aDesc
, int aWidth
, int aHeight
);
282 bool Serialize(mozilla::layers::SurfaceDescriptor
& aOutDescriptor
);
284 DMABufSurfaceYUV
* GetAsDMABufSurfaceYUV() { return this; };
286 int GetWidth(int aPlane
= 0) { return mWidth
[aPlane
]; }
287 int GetHeight(int aPlane
= 0) { return mHeight
[aPlane
]; }
288 mozilla::gfx::SurfaceFormat
GetFormat();
289 mozilla::gfx::SurfaceFormat
GetFormatGL();
291 bool CreateTexture(mozilla::gl::GLContext
* aGLContext
, int aPlane
= 0);
292 void ReleaseTextures();
294 void ReleaseSurface();
296 GLuint
GetTexture(int aPlane
= 0) { return mTexture
[aPlane
]; };
297 EGLImageKHR
GetEGLImage(int aPlane
= 0) { return mEGLImage
[aPlane
]; };
299 int GetTextureCount();
301 void SetYUVColorSpace(mozilla::gfx::YUVColorSpace aColorSpace
) {
302 mColorSpace
= aColorSpace
;
304 mozilla::gfx::YUVColorSpace
GetYUVColorSpace() { return mColorSpace
; }
308 bool UpdateYUVData(void** aPixelData
, int* aLineSizes
);
309 bool UpdateYUVData(const VADRMPRIMESurfaceDescriptor
& aDesc
, int aWidth
,
312 bool VerifyTextureCreation();
317 bool Create(const mozilla::layers::SurfaceDescriptor
& aDesc
);
318 bool Create(int aWidth
, int aHeight
, void** aPixelData
, int* aLineSizes
);
319 bool CreateYUVPlane(int aPlane
, int aWidth
, int aHeight
, int aDrmFormat
);
320 void UpdateYUVPlane(int aPlane
, void* aPixelData
, int aLineSize
);
322 bool ImportSurfaceDescriptor(
323 const mozilla::layers::SurfaceDescriptorDMABuf
& aDesc
);
325 bool OpenFileDescriptorForPlane(const mozilla::MutexAutoLock
& aProofOfLock
,
327 void CloseFileDescriptorForPlane(const mozilla::MutexAutoLock
& aProofOfLock
,
328 int aPlane
, bool aForceClose
);
330 bool CreateEGLImage(mozilla::gl::GLContext
* aGLContext
, int aPlane
);
331 void ReleaseEGLImages(mozilla::gl::GLContext
* aGLContext
);
333 int mWidth
[DMABUF_BUFFER_PLANES
];
334 int mHeight
[DMABUF_BUFFER_PLANES
];
335 // Aligned size of the surface imported from VADRMPRIMESurfaceDescriptor.
336 // It's used only internally to create EGLImage as some GL drivers
337 // needs that (Bug 1724385).
338 int mWidthAligned
[DMABUF_BUFFER_PLANES
];
339 int mHeightAligned
[DMABUF_BUFFER_PLANES
];
340 EGLImageKHR mEGLImage
[DMABUF_BUFFER_PLANES
];
341 GLuint mTexture
[DMABUF_BUFFER_PLANES
];
342 mozilla::gfx::YUVColorSpace mColorSpace
=
343 mozilla::gfx::YUVColorSpace::Default
;