File: wayland_buffer_manager_host.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (229 lines) | stat: -rw-r--r-- 10,240 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_BUFFER_MANAGER_HOST_H_
#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_BUFFER_MANAGER_HOST_H_

#include <list>
#include <memory>
#include <string>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/files/scoped_file.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "ui/gfx/frame_data.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/gpu_fence_handle.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/presentation_feedback.h"
#include "ui/gfx/swap_result.h"
#include "ui/ozone/platform/wayland/common/wayland_object.h"
#include "ui/ozone/platform/wayland/common/wayland_util.h"
#include "ui/ozone/platform/wayland/mojom/wayland_buffer_manager.mojom.h"

namespace ui {

class DrmSyncobjIoctlWrapper;
class WaylandBufferBacking;
class WaylandBufferHandle;
class WaylandConnection;
class WaylandWindow;
class WaylandSurface;

// This is the buffer manager which creates wl_buffers based on dmabuf (hw
// accelerated compositing) or shared memory (software compositing) and uses
// internal representation of surfaces, which are used to store buffers
// associated with the WaylandWindow.
class WaylandBufferManagerHost : public ozone::mojom::WaylandBufferManagerHost {
 public:
  explicit WaylandBufferManagerHost(WaylandConnection* connection);

  WaylandBufferManagerHost(const WaylandBufferManagerHost&) = delete;
  WaylandBufferManagerHost& operator=(const WaylandBufferManagerHost&) = delete;

  ~WaylandBufferManagerHost() override;

  void SetTerminateGpuCallback(
      base::OnceCallback<void(std::string)> terminate_gpu_cb);

  // Returns bound pointer to own mojo interface. If there were previous
  // interface bindings, it will be unbound and the state of the
  // |buffer_manager_| will be cleared.
  mojo::PendingRemote<ozone::mojom::WaylandBufferManagerHost> BindInterface();

  // Unbinds the interface and clears the state of the |buffer_manager_|. Used
  // only when the GPU channel, which uses the mojo pipe to this interface, is
  // destroyed.
  void OnChannelDestroyed();

  // Called by WaylandFrameManager if overlay data is invalid.
  void OnCommitOverlayError(const std::string& message);

  // Returns supported buffer formats either from zwp_linux_dmabuf or wl_drm.
  wl::BufferFormatsWithModifiersMap GetSupportedBufferFormats() const;

  bool SupportsDmabuf() const;
  bool SupportsAcquireFence() const;
  bool SupportsViewporter() const;
  bool SupportsOverlays() const;
  bool SupportsSinglePixelBuffer() const;

  // ozone::mojom::WaylandBufferManagerHost overrides:
  //
  // These overridden methods below are invoked by the GPU when hardware
  // accelerated rendering is used.
  void SetWaylandBufferManagerGpu(
      mojo::PendingAssociatedRemote<ozone::mojom::WaylandBufferManagerGpu>
          buffer_manager_gpu_associated) override;
  //
  // Called by the GPU and asks to import a wl_buffer based on a gbm file
  // descriptor using zwp_linux_dmabuf protocol. Check comments in the
  // ui/ozone/platform/wayland/mojom/wayland_buffer_manager.mojom.
  void CreateDmabufBasedBuffer(mojo::PlatformHandle dmabuf_fd,
                               const gfx::Size& size,
                               const std::vector<uint32_t>& strides,
                               const std::vector<uint32_t>& offsets,
                               const std::vector<uint64_t>& modifiers,
                               uint32_t format,
                               uint32_t planes_count,
                               uint32_t buffer_id) override;
  // Called by the GPU and asks to import a wl_buffer based on a shared memory
  // file descriptor using wl_shm protocol. Check comments in the
  // ui/ozone/platform/wayland/mojom/wayland_buffer_manager.mojom.
  void CreateShmBasedBuffer(mojo::PlatformHandle shm_fd,
                            uint64_t length,
                            const gfx::Size& size,
                            uint32_t buffer_id) override;
  // Called by the GPU and asks to create a single pixel wl_buffer. Check
  // comments in the
  // ui/ozone/platform/wayland/mojom/wayland_buffer_manager.mojom. The
  // availability of this depends on existence of single pixel buffer protocol.
  void CreateSinglePixelBuffer(const SkColor4f& color,
                               uint32_t buffer_id) override;

  // Called by the GPU to destroy the imported wl_buffer with a |buffer_id|.
  void DestroyBuffer(uint32_t buffer_id) override;
  // Called by the GPU and asks to configure the surface/subsurfaces and attach
  // wl_buffers to WaylandWindow with the specified |widget|. Calls OnSubmission
  // and OnPresentation on successful swap and pixels presented.
  void CommitOverlays(gfx::AcceleratedWidget widget,
                      uint32_t frame_id,
                      const gfx::FrameData& data,
                      std::vector<wl::WaylandOverlayConfig> overlays) override;

  // Ensures a WaylandBufferHandle of |buffer_id| is created for the
  // |requestor|, with its wl_buffer object requested via Wayland. Returns said
  // buffer handle.
  WaylandBufferHandle* EnsureBufferHandle(WaylandSurface* requestor,
                                          uint32_t buffer_id);

  // Gets the WaylandBufferHandle of |buffer_id| used for |requestor|.
  WaylandBufferHandle* GetBufferHandle(WaylandSurface* requestor,
                                       uint32_t buffer_id);

  // Gets the buffer format of |buffer_id| used for |requestor| if it is a
  // DMA based buffer.
  uint32_t GetBufferFormat(WaylandSurface* requestor, uint32_t buffer_id);

  // Tells the |buffer_manager_gpu_ptr_| the result of a swap call and provides
  // it with the presentation feedback.
  void OnSubmission(
      gfx::AcceleratedWidget widget,
      uint32_t frame_id,
      const gfx::SwapResult& swap_result,
      gfx::GpuFenceHandle release_fence,
      const std::vector<wl::WaylandPresentationInfo>& presentation_infos);
  void OnPresentation(
      gfx::AcceleratedWidget widget,
      const std::vector<wl::WaylandPresentationInfo>& presentation_infos);

  // Inserts a sync_file into the write fence list of the DMA-BUF. When the
  // compositor tries to read from this DMA-BUF via GL, the kernel will
  // automatically force its GPU context to wait on all write fences in the
  // DMA-BUF, including the fence we inserted. This is used to synchronize with
  // compositors that don't support the
  // linux-explicit-synchronization-unstable-v1 protocol. Requires Linux 6.0 or
  // higher.
  void InsertAcquireFence(uint32_t buffer_id, int sync_fd);

  // Extracts a sync_file that represents all pending fences inside the DMA-BUF
  // kernel object. When the compositor reads the DMA-BUF from GL, the kernel
  // automatically adds a completion fence to the read fences list of the
  // DMA-BUF that will be signalled once the read operation completes. This is
  // used to synchronize with compositors that don't support the
  // linux-explicit-synchronization-unstable-v1 protocol. Requires Linux 6.0 or
  // higher.
  base::ScopedFD ExtractReleaseFence(uint32_t buffer_id);

  static bool SupportsImplicitSyncInterop();

  DrmSyncobjIoctlWrapper* drm_syncobj_wrapper() {
    return drm_syncobj_wrapper_.get();
  }

  void SetDrmSyncobjWrapper(std::unique_ptr<DrmSyncobjIoctlWrapper> wrapper);

 private:
  // Validates data sent from GPU. If invalid, returns false and sets an error
  // message to |error_message_|.
  bool ValidateDataFromGpu(const base::ScopedFD& file,
                           const gfx::Size& size,
                           const std::vector<uint32_t>& strides,
                           const std::vector<uint32_t>& offsets,
                           const std::vector<uint64_t>& modifiers,
                           uint32_t format,
                           uint32_t planes_count,
                           uint32_t buffer_id);
  bool ValidateBufferIdFromGpu(uint32_t buffer_id);
  bool ValidateDataFromGpu(const base::ScopedFD& file,
                           size_t length,
                           const gfx::Size& size,
                           uint32_t buffer_id);
  bool ValidateDataFromGpu(const gfx::Size& size, uint32_t buffer_id);
  bool ValidateBufferExistence(uint32_t buffer_id);

  // Terminates the GPU process on invalid data received
  void TerminateGpuProcess();

  // Set when invalid data is received from the GPU process.
  std::string error_message_;

  // Non-owned pointer to the main connection.
  const raw_ptr<WaylandConnection> connection_;

  mojo::AssociatedRemote<ozone::mojom::WaylandBufferManagerGpu>
      buffer_manager_gpu_associated_;
  mojo::Receiver<ozone::mojom::WaylandBufferManagerHost> receiver_;

  // A callback, which is used to terminate a GPU process in case of invalid
  // data sent by the GPU to the browser process.
  base::OnceCallback<void(std::string)> terminate_gpu_cb_;

  // This needs to be before |buffer_backings_| so that it is deleted after
  // buffer handles which need this at the time of destruction when explicit
  // sync is available.
  // TODO(crbug.com/367623923) If DrmRenderNodePathFinder could cache the path
  // we could initialize this in the constructor for this class using a
  // DrmRenderNodeHandle, passing it the path obtained from the
  // DrmRenderNodePathFinder and remove SetDrm() instead of doing this in
  // OzonePlatformWayland::InitializeUI() which is where it is done currently to
  // limit the number of path lookups.
  std::unique_ptr<DrmSyncobjIoctlWrapper> drm_syncobj_wrapper_;

  // Maps buffer_id's to corresponding WaylandBufferBacking objects.
  base::flat_map<uint32_t, std::unique_ptr<WaylandBufferBacking>>
      buffer_backings_;

  base::flat_map<uint32_t, base::ScopedFD> dma_buffers_;
};

}  // namespace ui

#endif  // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_BUFFER_MANAGER_HOST_H_