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_
|