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_WINDOW_SURFACE_WAYLAND_MULTI_BUFFER_H
8 #define _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_WAYLAND_MULTI_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 #include "nsWindow.h"
16 #include "WaylandShmBuffer.h"
17 #include "WindowSurface.h"
18 
19 namespace mozilla::widget {
20 
21 using gfx::DrawTarget;
22 
23 // WindowSurfaceWaylandMB is an abstraction for wl_surface
24 // and related management
25 class WindowSurfaceWaylandMB : public WindowSurface {
26  public:
27   explicit WindowSurfaceWaylandMB(nsWindow* aWindow);
28   ~WindowSurfaceWaylandMB() = default;
29 
30   // Lock() / Commit() are called by gecko when Firefox
31   // wants to display something. Lock() returns a DrawTarget
32   // where gecko paints. When gecko is done it calls Commit()
33   // and we try to send the DrawTarget (backed by wl_buffer)
34   // to wayland compositor.
35   //
36   // If we fail (wayland compositor is busy,
37   // wl_surface is not created yet) we queue the painting
38   // and we send it to wayland compositor in FrameCallbackHandler()/
39   // FlushPendingCommits().
40   already_AddRefed<DrawTarget> Lock(
41       const LayoutDeviceIntRegion& aRegion) override;
42   void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final;
GetWaylandDisplay()43   RefPtr<nsWaylandDisplay> GetWaylandDisplay() { return mWaylandDisplay; };
44 
45   static void BufferReleaseCallbackHandler(void* aData, wl_buffer* aBuffer);
46 
47  private:
48   RefPtr<WaylandShmBuffer> GetWaylandBuffer();
49   RefPtr<WaylandShmBuffer> ObtainBufferFromPool(
50       const LayoutDeviceIntSize& aSize);
51   void ReturnBufferToPool(const RefPtr<WaylandShmBuffer>& aBuffer);
52   void EnforcePoolSizeLimit(const MutexAutoLock& aLock);
53   void PrepareBufferForFrame(const MutexAutoLock& aLock);
54   void HandlePartialUpdate(const MutexAutoLock& aLock,
55                            const LayoutDeviceIntRegion& aInvalidRegion);
56   void IncrementBufferAge();
57   void BufferReleaseCallbackHandler(wl_buffer* aBuffer);
58 
59   mozilla::Mutex mSurfaceLock;
60 
61   nsWindow* mWindow;
62   RefPtr<nsWaylandDisplay> mWaylandDisplay;
63   RefPtr<WaylandShmBuffer> mWaylandBuffer;
64   LayoutDeviceIntSize mMozContainerSize;
65 
66   // partial damage
67   RefPtr<WaylandShmBuffer> mPreviousWaylandBuffer;
68   LayoutDeviceIntRegion mPreviousInvalidRegion;
69 
70   // buffer pool
71   nsTArray<RefPtr<WaylandShmBuffer>> mInUseBuffers;
72   nsTArray<RefPtr<WaylandShmBuffer>> mAvailableBuffers;
73 };
74 
75 }  // namespace mozilla::widget
76 
77 #endif  // _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_WAYLAND_MULTI_BUFFER_H
78