1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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/. */
6 
7 #ifndef _MOZILLA_WIDGET_GTK_WAYLAND_SHM_BUFFER_H
8 #define _MOZILLA_WIDGET_GTK_WAYLAND_SHM_BUFFER_H
9 
10 #include "mozilla/gfx/2D.h"
11 #include "mozilla/gfx/Types.h"
12 #include "mozilla/Mutex.h"
13 #include "nsTArray.h"
14 #include "nsWaylandDisplay.h"
15 
16 namespace mozilla::widget {
17 
18 // Allocates and owns shared memory for Wayland drawing surface
19 class WaylandShmPool {
20  public:
21   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WaylandShmPool);
22 
23   static RefPtr<WaylandShmPool> Create(
24       const RefPtr<nsWaylandDisplay>& aWaylandDisplay, int aSize);
25 
GetShmPool()26   wl_shm_pool* GetShmPool() { return mShmPool; };
GetImageData()27   void* GetImageData() { return mImageData; };
28 
29  private:
30   explicit WaylandShmPool(int aSize);
31   ~WaylandShmPool();
32 
33   wl_shm_pool* mShmPool;
34   int mShmPoolFd;
35   int mAllocatedSize;
36   void* mImageData;
37 };
38 
39 // Holds actual graphics data for wl_surface
40 class WaylandShmBuffer {
41  public:
42   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WaylandShmBuffer);
43 
44   static RefPtr<WaylandShmBuffer> Create(
45       const RefPtr<nsWaylandDisplay>& aWaylandDisplay,
46       const LayoutDeviceIntSize& aSize);
47 
48   already_AddRefed<gfx::DrawTarget> Lock();
49 
50   void AttachAndCommit(wl_surface* aSurface);
IsAttached()51   bool IsAttached() { return mAttached; }
52   void Clear();
53 
54   static void BufferReleaseCallbackHandler(void* aData, wl_buffer* aBuffer);
SetBufferReleaseFunc(void (* aBufferReleaseFunc)(void * aData,wl_buffer * aBuffer))55   void SetBufferReleaseFunc(void (*aBufferReleaseFunc)(void* aData,
56                                                        wl_buffer* aBuffer)) {
57     mBufferReleaseFunc = aBufferReleaseFunc;
58   }
SetBufferReleaseData(void * aBufferReleaseData)59   void SetBufferReleaseData(void* aBufferReleaseData) {
60     mBufferReleaseData = aBufferReleaseData;
61   }
62 
GetBufferAge()63   size_t GetBufferAge() { return mBufferAge; };
GetShmPool()64   RefPtr<WaylandShmPool> GetShmPool() { return mShmPool; }
GetSize()65   LayoutDeviceIntSize GetSize() { return mSize; };
GetSurfaceFormat()66   static gfx::SurfaceFormat GetSurfaceFormat() { return mFormat; }
GetWlBuffer()67   wl_buffer* GetWlBuffer() { return mWLBuffer; };
IsMatchingSize(const LayoutDeviceIntSize & aSize)68   bool IsMatchingSize(const LayoutDeviceIntSize& aSize) {
69     return aSize == mSize;
70   }
71 
IncrementBufferAge()72   void IncrementBufferAge() { mBufferAge++; };
ResetBufferAge()73   void ResetBufferAge() { mBufferAge = 0; };
74 
75 #ifdef MOZ_LOGGING
76   void DumpToFile(const char* aHint);
77 #endif
78 
79  private:
80   explicit WaylandShmBuffer(const LayoutDeviceIntSize& aSize);
81   ~WaylandShmBuffer();
82 
83   void BufferReleaseCallbackHandler(wl_buffer* aBuffer);
84 
85   // WaylandShmPoolMB provides actual shared memory we draw into
86   RefPtr<WaylandShmPool> mShmPool;
87 
88   // wl_buffer is a wayland object that encapsulates the shared memory
89   // and passes it to wayland compositor by wl_surface object.
90   wl_buffer* mWLBuffer;
91 
92   void (*mBufferReleaseFunc)(void* aData, wl_buffer* aBuffer);
93   void* mBufferReleaseData;
94 
95   LayoutDeviceIntSize mSize;
96   size_t mBufferAge;
97   bool mAttached;
98   static gfx::SurfaceFormat mFormat;
99 
100 #ifdef MOZ_LOGGING
101   static int mDumpSerial;
102   static char* mDumpDir;
103 #endif
104 };
105 
106 }  // namespace mozilla::widget
107 
108 #endif  // _MOZILLA_WIDGET_GTK_WAYLAND_SHM_BUFFER_H
109