Bug 1769547 - Do not MOZ_CRASH() on missing process r=nika
[gecko.git] / widget / gtk / DMABufSurface.h
blob8cb4a7db9ee7df3926ab24a9d2d7b9d0ff7526a1
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__
10 #include <stdint.h>
11 #include "mozilla/widget/nsWaylandDisplay.h"
12 #include "mozilla/widget/va_drmcommon.h"
13 #include "GLTypes.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
22 #endif
23 #ifndef VA_FOURCC_YV12
24 # define VA_FOURCC_YV12 0x32315659
25 #endif
26 #ifndef VA_FOURCC_P010
27 # define VA_FOURCC_P010 0x30313050
28 #endif
30 namespace mozilla {
31 namespace gfx {
32 class SourceSurface;
34 namespace layers {
35 class SurfaceDescriptor;
36 class SurfaceDescriptorDMABuf;
37 } // namespace layers
38 namespace gl {
39 class GLContext;
41 } // namespace mozilla
43 typedef enum {
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,
52 } DMABufSurfaceFlags;
54 class DMABufSurfaceRGBA;
55 class DMABufSurfaceYUV;
57 class DMABufSurface {
58 public:
59 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DMABufSurface)
61 enum SurfaceType {
62 SURFACE_RGBA,
63 SURFACE_NV12,
64 SURFACE_YUV420,
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,
84 int aPlane = 0) = 0;
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;
107 void FenceSet();
108 void FenceWait();
109 void FenceDelete();
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
113 // engine.
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.
136 void GlobalRefAdd();
137 void GlobalRefRelease();
139 // Release all underlying data.
140 virtual void ReleaseSurface() = 0;
142 #ifdef DEBUG
143 virtual void DumpToFile(const char* pFile){};
144 #endif
146 DMABufSurface(SurfaceType aSurfaceType);
148 protected:
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];
187 int mSyncFd;
188 EGLSyncKHR mSync;
189 RefPtr<mozilla::gl::GLContext> mGL;
191 int mGlobalRefCountFd;
192 uint32_t mUID;
193 mozilla::Mutex mSurfaceLock MOZ_UNANNOTATED;
195 mozilla::gfx::ColorRange mColorRange = mozilla::gfx::ColorRange::LIMITED;
198 class DMABufSurfaceRGBA : public DMABufSurface {
199 public:
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; }
207 void Clear();
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();
217 bool HasAlpha();
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; };
241 #ifdef DEBUG
242 virtual void DumpToFile(const char* pFile);
243 #endif
245 DMABufSurfaceRGBA();
247 private:
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,
256 int aPlane);
257 void CloseFileDescriptorForPlane(const mozilla::MutexAutoLock& aProofOfLock,
258 int aPlane, bool aForceClose);
260 private:
261 int mSurfaceFlags;
263 int mWidth;
264 int mHeight;
265 mozilla::widget::GbmFormat* mGmbFormat;
267 EGLImageKHR mEGLImage;
268 GLuint mTexture;
269 uint32_t mGbmBufferFlags;
270 wl_buffer* mWlBuffer;
273 class DMABufSurfaceYUV : public DMABufSurface {
274 public:
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; }
306 DMABufSurfaceYUV();
308 bool UpdateYUVData(void** aPixelData, int* aLineSizes);
309 bool UpdateYUVData(const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth,
310 int aHeight);
312 bool VerifyTextureCreation();
314 private:
315 ~DMABufSurfaceYUV();
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,
326 int aPlane);
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;
346 #endif