Everywhere: Use IOSurface as backing store on macOS

Using mmap-allocated memory for backing stores does not allow us to
benefit from using GPU-accelerated painting, because all the performance
increase we get is mostly negated by reading the GPU-allocated texture
back into RAM, so it can be shared with the browser process.

With IOSurface, we get a framebuffer that is both shareable between
processes and can be used as underlying memory for an OpenGL/Metal
texture.

This change does not yet benefit from using IOSurface and merely wraps
them into Gfx::Bitmap to be used by the CPU painter.
This commit is contained in:
Aliaksandr Kalenik 2024-06-20 21:34:51 +03:00 committed by Andreas Kling
commit c92f8ab1ea
Notes: sideshowbarker 2024-07-16 20:51:53 +09:00
15 changed files with 266 additions and 56 deletions

View file

@ -49,4 +49,8 @@ class UDPSocket;
enum class TimerShouldFireWhenNotVisible;
#ifdef AK_OS_MACH
class MachPort;
#endif
}

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Platform.h>
#if !defined(AK_OS_MACH)
# error "This file is only available on Mach platforms"
#endif
#include <mach/mach.h>
namespace Core::Platform {
struct MessageBodyWithSelfTaskPort {
mach_msg_body_t body;
mach_msg_port_descriptor_t port_descriptor;
mach_msg_audit_trailer_t trailer;
};
struct MessageWithSelfTaskPort {
mach_msg_header_t header;
mach_msg_body_t body;
mach_msg_port_descriptor_t port_descriptor;
};
struct BackingStoreMetadata {
u64 page_id { 0 };
i32 back_backing_store_id { 0 };
i32 front_backing_store_id { 0 };
};
struct MessageBodyWithBackingStores {
mach_msg_body_t body;
mach_msg_port_descriptor_t front_descriptor;
mach_msg_port_descriptor_t back_descriptor;
BackingStoreMetadata metadata;
mach_msg_audit_trailer_t trailer;
};
struct MessageWithBackingStores {
mach_msg_header_t header;
mach_msg_body_t body;
mach_msg_port_descriptor_t front_descriptor;
mach_msg_port_descriptor_t back_descriptor;
BackingStoreMetadata metadata;
};
struct ReceivedMachMessage {
mach_msg_header_t header;
union {
MessageBodyWithSelfTaskPort parent;
MessageBodyWithBackingStores parent_iosurface;
} body;
};
static constexpr mach_msg_id_t SELF_TASK_PORT_MESSAGE_ID = 0x1234CAFE;
static constexpr mach_msg_id_t BACKING_STORE_IOSURFACES_MESSAGE_ID = 0x1234CAFF;
}

View file

@ -13,6 +13,7 @@
#include <AK/ByteString.h>
#include <AK/Time.h>
#include <LibCore/MachPort.h>
#include <LibCore/Platform/MachMessageTypes.h>
#include <LibCore/Platform/ProcessStatisticsMach.h>
namespace Core::Platform {
@ -75,17 +76,17 @@ ErrorOr<void> update_process_statistics(ProcessStatistics& statistics)
return {};
}
void register_with_mach_server(ByteString const& server_name)
MachPort register_with_mach_server(ByteString const& server_name)
{
auto server_port_or_error = Core::MachPort::look_up_from_bootstrap_server(server_name);
if (server_port_or_error.is_error()) {
dbgln("Failed to lookup server port: {}", server_port_or_error.error());
return;
VERIFY_NOT_REACHED();
}
auto server_port = server_port_or_error.release_value();
// Send our own task port to the server so they can query statistics about us
ChildPortMessage message {};
MessageWithSelfTaskPort message {};
message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSGH_BITS_ZERO) | MACH_MSGH_BITS_COMPLEX;
message.header.msgh_size = sizeof(message);
message.header.msgh_remote_port = server_port.port();
@ -101,8 +102,10 @@ void register_with_mach_server(ByteString const& server_name)
auto const send_result = mach_msg(&message.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT, message.header.msgh_size, 0, MACH_PORT_NULL, timeout, MACH_PORT_NULL);
if (send_result != KERN_SUCCESS) {
dbgln("Failed to send message to server: {}", mach_error_string(send_result));
return;
VERIFY_NOT_REACHED();
}
return server_port;
}
}

View file

@ -17,21 +17,6 @@
namespace Core::Platform {
struct ChildPortMessage {
mach_msg_header_t header;
mach_msg_body_t body;
mach_msg_port_descriptor_t port_descriptor;
};
struct ParentPortMessage {
mach_msg_header_t header;
mach_msg_body_t body;
mach_msg_port_descriptor_t port_descriptor;
mach_msg_audit_trailer_t trailer; // for the child's pid
};
static constexpr mach_msg_id_t SELF_TASK_PORT_MESSAGE_ID = 0x1234CAFE;
void register_with_mach_server(ByteString const& server_name);
MachPort register_with_mach_server(ByteString const& server_name);
}