Bug 1931425 - Limit how often moz-label's #setStyles runs r=reusable-components-revie...
[gecko.git] / widget / gtk / WaylandBuffer.h
blobda2482833018a032e46a279367f2110e655f3304
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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 _MOZILLA_WIDGET_GTK_WAYLAND_BUFFER_H
8 #define _MOZILLA_WIDGET_GTK_WAYLAND_BUFFER_H
10 #include "DMABufSurface.h"
11 #include "GLContext.h"
12 #include "MozFramebuffer.h"
13 #include "mozilla/ipc/SharedMemory.h"
14 #include "mozilla/gfx/2D.h"
15 #include "mozilla/gfx/Types.h"
16 #include "mozilla/Mutex.h"
17 #include "mozilla/RefPtr.h"
18 #include "nsTArray.h"
19 #include "nsWaylandDisplay.h"
20 #include "WaylandSurface.h"
22 namespace mozilla::widget {
24 // Allocates and owns shared memory for Wayland drawing surface
25 class WaylandShmPool {
26 public:
27 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WaylandShmPool);
29 static RefPtr<WaylandShmPool> Create(nsWaylandDisplay* aWaylandDisplay,
30 int aSize);
32 wl_shm_pool* GetShmPool() { return mShmPool; };
33 void* GetImageData();
35 private:
36 WaylandShmPool() = default;
37 ~WaylandShmPool();
39 wl_shm_pool* mShmPool = nullptr;
40 void* mImageData = nullptr;
41 RefPtr<ipc::SharedMemory> mShm;
42 int mSize = 0;
45 class WaylandBuffer {
46 public:
47 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WaylandBuffer);
49 virtual already_AddRefed<gfx::DrawTarget> Lock() { return nullptr; };
50 virtual void* GetImageData() { return nullptr; }
51 virtual GLuint GetTexture() { return 0; }
52 virtual void DestroyGLResources() {};
53 virtual gfx::SurfaceFormat GetSurfaceFormat() = 0;
55 LayoutDeviceIntSize GetSize() { return mSize; };
56 bool IsMatchingSize(const LayoutDeviceIntSize& aSize) {
57 return aSize == mSize;
60 bool IsAttached() { return !!mSurface; }
62 // Lend wl_buffer to WaylandSurface to attach.
63 // We store reference to WaylandSurface unless we don't have
64 // wl_buffer available.
66 // At also marks buffer as attached.
67 wl_buffer* BorrowBuffer(RefPtr<WaylandSurface> aWaylandSurface);
69 // Return lended buffer, called by aWaylandSurface.
70 void ReturnBuffer(RefPtr<WaylandSurface> aWaylandSurface);
72 // Called by Wayland compostor when buffer is released/deleted by
73 // Wayland compostor.
75 // There are two cases how buffer can be detached:
76 // 1) detach call from Wayland compostor, wl_buffer may be kept around.
77 // 2) detach from WaylandSurface - internal wl_buffer is deleted,
78 // for instance on Unmap when wl_surface becomes invisible.
79 void BufferDetachedCallbackHandler(wl_buffer* aBuffer, bool aWlBufferDeleted);
81 protected:
82 explicit WaylandBuffer(const LayoutDeviceIntSize& aSize);
83 virtual ~WaylandBuffer() = default;
85 // Create and return wl_buffer for underlying memory buffer if it's missing.
86 virtual bool CreateWlBuffer() = 0;
88 // Delete wl_buffer. It only releases Wayland interface over underlying
89 // memory, doesn't affect actual buffer content but only connection
90 // to Wayland compositor.
91 void DeleteWlBuffer();
92 wl_buffer* GetWlBuffer() { return mWLBuffer; }
93 bool HasWlBuffer() { return !!mWLBuffer; }
95 bool IsWaitingToBufferDelete() const { return !!mBufferDeleteSyncCallback; }
97 // We need to protect buffer release sequence as it can happen
98 // from Main thread (Wayland compositor) and Rendering thread.
99 mozilla::Mutex mBufferReleaseMutex{"WaylandBufferRelease"};
101 // wl_buffer delete is not atomic, we need to wait until it's finished.
102 wl_callback* mBufferDeleteSyncCallback = nullptr;
104 // wl_buffer is a wayland object that encapsulates the shared/dmabuf memory
105 // and passes it to wayland compositor by wl_surface object.
106 wl_buffer* mWLBuffer = nullptr;
108 LayoutDeviceIntSize mSize;
109 // WaylandSurface where we're attached to.
110 RefPtr<WaylandSurface> mSurface;
111 static gfx::SurfaceFormat sFormat;
114 // Holds actual graphics data for wl_surface
115 class WaylandBufferSHM final : public WaylandBuffer {
116 public:
117 static RefPtr<WaylandBufferSHM> Create(const LayoutDeviceIntSize& aSize);
119 void ReleaseWlBuffer();
120 already_AddRefed<gfx::DrawTarget> Lock() override;
121 void* GetImageData() override { return mShmPool->GetImageData(); }
123 gfx::SurfaceFormat GetSurfaceFormat() override {
124 return gfx::SurfaceFormat::B8G8R8A8;
127 void Clear();
128 size_t GetBufferAge() { return mBufferAge; };
129 RefPtr<WaylandShmPool> GetShmPool() { return mShmPool; }
131 void IncrementBufferAge() { mBufferAge++; };
132 void ResetBufferAge() { mBufferAge = 0; };
134 #ifdef MOZ_LOGGING
135 void DumpToFile(const char* aHint);
136 #endif
138 protected:
139 bool CreateWlBuffer() override;
141 private:
142 explicit WaylandBufferSHM(const LayoutDeviceIntSize& aSize);
143 ~WaylandBufferSHM() override;
145 // WaylandShmPoolMB provides actual shared memory we draw into
146 RefPtr<WaylandShmPool> mShmPool;
148 size_t mBufferAge = 0;
150 #ifdef MOZ_LOGGING
151 static int mDumpSerial;
152 static char* mDumpDir;
153 #endif
156 class WaylandBufferDMABUF final : public WaylandBuffer {
157 public:
158 static already_AddRefed<WaylandBufferDMABUF> CreateRGBA(
159 const LayoutDeviceIntSize& aSize, gl::GLContext* aGL,
160 RefPtr<DRMFormat> aFormat);
161 static already_AddRefed<WaylandBufferDMABUF> CreateExternal(
162 RefPtr<DMABufSurface> aSurface);
164 GLuint GetTexture() override { return mDMABufSurface->GetTexture(); };
165 void DestroyGLResources() override { mDMABufSurface->ReleaseTextures(); };
166 gfx::SurfaceFormat GetSurfaceFormat() override {
167 return mDMABufSurface->GetFormat();
170 protected:
171 bool CreateWlBuffer() override;
173 private:
174 explicit WaylandBufferDMABUF(const LayoutDeviceIntSize& aSize);
175 ~WaylandBufferDMABUF();
177 RefPtr<DMABufSurface> mDMABufSurface;
180 } // namespace mozilla::widget
182 #endif // _MOZILLA_WIDGET_GTK_WAYLAND_BUFFER_H