2026-04-07 13:35:26 -03:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2026, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <AK/Error.h>
|
|
|
|
|
#include <AK/Noncopyable.h>
|
LibGfx+LibWeb: Add Linux dmabuf backing stores to SharedImage
On Linux builds with Vulkan, WebContent already paints into GPU-backed
Skia surfaces, but the backing store shared with the UI process was
still a CPU ShareableBitmap. That forced every flush to read the GPU
image back into a bitmap so the UI could sample it, defeating most of
the benefit of GPU painting.
Teach SharedImage to carry a LinuxDmaBufHandle alongside ShareableBitmap
as a Variant, with a tagged IPC encoding and an fd clone on encode so
both processes own an independent handle. When USE_VULKAN_DMABUF_IMAGES
is enabled, BackingStoreManager now allocates the front/back buffers as
linear-modifier Vulkan images and publishes their dmabuf fds to the UI;
the Skia painting surfaces wrap those Vulkan images directly, so no
readback is needed. The old shareable-bitmap path is preserved as a
fallback for the non-Vulkan case and when image creation fails.
On the receive side, SharedImageBuffer::import_from_shared_image mmaps
a linear dmabuf to reconstruct a CPU Bitmap, keeping existing consumers
that expect CPU access working unchanged.
VulkanImage memory type selection is factored into a small helper, and
linear images now request host-visible (cached if available) memory
rather than device-local, since a linear dmabuf has to be CPU-mappable
on the importer side.
2026-04-07 15:38:22 -03:00
|
|
|
#include <AK/Variant.h>
|
|
|
|
|
#include <LibGfx/Bitmap.h>
|
|
|
|
|
#include <LibGfx/Forward.h>
|
|
|
|
|
#include <LibGfx/ShareableBitmap.h>
|
|
|
|
|
#include <LibIPC/File.h>
|
2026-04-07 13:35:26 -03:00
|
|
|
#include <LibIPC/Forward.h>
|
|
|
|
|
|
|
|
|
|
#ifdef AK_OS_MACOS
|
|
|
|
|
# include <LibCore/MachPort.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace Gfx {
|
|
|
|
|
|
|
|
|
|
class SharedImageBuffer;
|
|
|
|
|
|
LibGfx+LibWeb: Add Linux dmabuf backing stores to SharedImage
On Linux builds with Vulkan, WebContent already paints into GPU-backed
Skia surfaces, but the backing store shared with the UI process was
still a CPU ShareableBitmap. That forced every flush to read the GPU
image back into a bitmap so the UI could sample it, defeating most of
the benefit of GPU painting.
Teach SharedImage to carry a LinuxDmaBufHandle alongside ShareableBitmap
as a Variant, with a tagged IPC encoding and an fd clone on encode so
both processes own an independent handle. When USE_VULKAN_DMABUF_IMAGES
is enabled, BackingStoreManager now allocates the front/back buffers as
linear-modifier Vulkan images and publishes their dmabuf fds to the UI;
the Skia painting surfaces wrap those Vulkan images directly, so no
readback is needed. The old shareable-bitmap path is preserved as a
fallback for the non-Vulkan case and when image creation fails.
On the receive side, SharedImageBuffer::import_from_shared_image mmaps
a linear dmabuf to reconstruct a CPU Bitmap, keeping existing consumers
that expect CPU access working unchanged.
VulkanImage memory type selection is factored into a small helper, and
linear images now request host-visible (cached if available) memory
rather than device-local, since a linear dmabuf has to be CPU-mappable
on the importer side.
2026-04-07 15:38:22 -03:00
|
|
|
#ifndef AK_OS_MACOS
|
|
|
|
|
struct LinuxDmaBufHandle {
|
|
|
|
|
BitmapFormat bitmap_format;
|
|
|
|
|
AlphaType alpha_type;
|
|
|
|
|
IntSize size;
|
|
|
|
|
u32 drm_format;
|
|
|
|
|
size_t pitch;
|
|
|
|
|
u64 modifier;
|
|
|
|
|
IPC::File file;
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef USE_VULKAN_DMABUF_IMAGES
|
|
|
|
|
struct VulkanImage;
|
|
|
|
|
SharedImage duplicate_shared_image(VulkanImage const&);
|
|
|
|
|
LinuxDmaBufHandle duplicate_linux_dmabuf_handle(VulkanImage const&);
|
|
|
|
|
#endif
|
|
|
|
|
|
2026-04-07 13:35:26 -03:00
|
|
|
class SharedImage {
|
|
|
|
|
AK_MAKE_NONCOPYABLE(SharedImage);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
SharedImage(SharedImage&&) = default;
|
|
|
|
|
SharedImage& operator=(SharedImage&&) = default;
|
|
|
|
|
~SharedImage() = default;
|
|
|
|
|
|
|
|
|
|
#ifdef AK_OS_MACOS
|
|
|
|
|
explicit SharedImage(Core::MachPort&&);
|
|
|
|
|
#else
|
|
|
|
|
explicit SharedImage(ShareableBitmap);
|
LibGfx+LibWeb: Add Linux dmabuf backing stores to SharedImage
On Linux builds with Vulkan, WebContent already paints into GPU-backed
Skia surfaces, but the backing store shared with the UI process was
still a CPU ShareableBitmap. That forced every flush to read the GPU
image back into a bitmap so the UI could sample it, defeating most of
the benefit of GPU painting.
Teach SharedImage to carry a LinuxDmaBufHandle alongside ShareableBitmap
as a Variant, with a tagged IPC encoding and an fd clone on encode so
both processes own an independent handle. When USE_VULKAN_DMABUF_IMAGES
is enabled, BackingStoreManager now allocates the front/back buffers as
linear-modifier Vulkan images and publishes their dmabuf fds to the UI;
the Skia painting surfaces wrap those Vulkan images directly, so no
readback is needed. The old shareable-bitmap path is preserved as a
fallback for the non-Vulkan case and when image creation fails.
On the receive side, SharedImageBuffer::import_from_shared_image mmaps
a linear dmabuf to reconstruct a CPU Bitmap, keeping existing consumers
that expect CPU access working unchanged.
VulkanImage memory type selection is factored into a small helper, and
linear images now request host-visible (cached if available) memory
rather than device-local, since a linear dmabuf has to be CPU-mappable
on the importer side.
2026-04-07 15:38:22 -03:00
|
|
|
explicit SharedImage(LinuxDmaBufHandle&&);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
#ifdef AK_OS_MACOS
|
|
|
|
|
Core::MachPort m_port;
|
|
|
|
|
#else
|
|
|
|
|
Variant<ShareableBitmap, LinuxDmaBufHandle> m_data;
|
2026-04-07 13:35:26 -03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
friend class SharedImageBuffer;
|
|
|
|
|
|
|
|
|
|
template<typename U>
|
|
|
|
|
friend ErrorOr<void> IPC::encode(IPC::Encoder&, U const&);
|
|
|
|
|
|
|
|
|
|
template<typename U>
|
|
|
|
|
friend ErrorOr<U> IPC::decode(IPC::Decoder&);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace IPC {
|
|
|
|
|
|
LibGfx+LibWeb: Add Linux dmabuf backing stores to SharedImage
On Linux builds with Vulkan, WebContent already paints into GPU-backed
Skia surfaces, but the backing store shared with the UI process was
still a CPU ShareableBitmap. That forced every flush to read the GPU
image back into a bitmap so the UI could sample it, defeating most of
the benefit of GPU painting.
Teach SharedImage to carry a LinuxDmaBufHandle alongside ShareableBitmap
as a Variant, with a tagged IPC encoding and an fd clone on encode so
both processes own an independent handle. When USE_VULKAN_DMABUF_IMAGES
is enabled, BackingStoreManager now allocates the front/back buffers as
linear-modifier Vulkan images and publishes their dmabuf fds to the UI;
the Skia painting surfaces wrap those Vulkan images directly, so no
readback is needed. The old shareable-bitmap path is preserved as a
fallback for the non-Vulkan case and when image creation fails.
On the receive side, SharedImageBuffer::import_from_shared_image mmaps
a linear dmabuf to reconstruct a CPU Bitmap, keeping existing consumers
that expect CPU access working unchanged.
VulkanImage memory type selection is factored into a small helper, and
linear images now request host-visible (cached if available) memory
rather than device-local, since a linear dmabuf has to be CPU-mappable
on the importer side.
2026-04-07 15:38:22 -03:00
|
|
|
#ifndef AK_OS_MACOS
|
|
|
|
|
template<>
|
|
|
|
|
ErrorOr<void> encode(Encoder&, Gfx::LinuxDmaBufHandle const&);
|
|
|
|
|
|
|
|
|
|
template<>
|
|
|
|
|
ErrorOr<Gfx::LinuxDmaBufHandle> decode(Decoder&);
|
|
|
|
|
#endif
|
|
|
|
|
|
2026-04-07 13:35:26 -03:00
|
|
|
template<>
|
|
|
|
|
ErrorOr<void> encode(Encoder&, Gfx::SharedImage const&);
|
|
|
|
|
|
|
|
|
|
template<>
|
|
|
|
|
ErrorOr<Gfx::SharedImage> decode(Decoder&);
|
|
|
|
|
|
|
|
|
|
}
|