#pragma once

#include <AK/NonnullRefPtr.h>
#include <AK/Optional.h>
#include <LibCore/AnonymousBuffer.h>
#include <LibGfx/CanvasCommandList.h>
#include <LibGfx/DecodedImageFrame.h>
#include <LibGfx/Point.h>
#include <LibGfx/Rect.h>
#include <LibGfx/ShareableBitmap.h>
#include <LibGfx/Size.h>
#include <LibMedia/VideoFrame.h>
#include <LibWeb/Compositor/Types.h>
#include <LibWeb/Forward.h>
#include <LibWeb/Painting/AccumulatedVisualContext.h>
#include <LibWeb/Painting/Canvas2DCommandStream.h>
#include <LibWeb/Painting/DisplayList.h>
#include <LibWeb/Painting/DisplayListResourceStorage.h>
#include <LibWeb/Painting/ScrollState.h>
#include <LibWeb/WebGL/Types.h>
#include <AK/Error.h>
#include <AK/MemoryStream.h>
#include <AK/OwnPtr.h>
#include <AK/Platform.h>
#include <AK/Result.h>
#include <AK/Utf8View.h>
#include <LibIPC/Attachment.h>
#include <LibIPC/Connection.h>
#include <LibIPC/Decoder.h>
#include <LibIPC/Encoder.h>
#include <LibIPC/File.h>
#include <LibIPC/Message.h>
#include <LibIPC/Stub.h>

#if defined(AK_COMPILER_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
#endif

namespace Messages::CompositorWebContentServer {

enum class MessageID : i32 {
    InitTransport = 1,
    InitTransportResponse = 2,
    SetParentContext = 3,
    StopPresentingToClient = 4,
    DestroyContext = 5,
    UpdateDisplayList = 6,
    UpdateImageFrameResources = 7,
    UpdateVisualContextTree = 8,
    UpdateScrollState = 9,
    UpdateVideoFrame = 10,
    ClearVideoFrame = 11,
    CreateCanvas2dContext = 12,
    CreateCanvas2dContextResponse = 13,
    UpdateCanvas2dStream = 14,
    DestroyCanvasContext = 15,
    GetCanvasPixels = 16,
    GetCanvasPixelsResponse = 17,
    CreateWebglContext = 18,
    CreateWebglContextResponse = 19,
    WebglCommands = 20,
    WebglPresentCanvas = 21,
    WebglSyncCall = 22,
    WebglSyncCallResponse = 23,
    WebglReadPixels = 24,
    WebglReadPixelsResponse = 25,
    WebglReadBufferSubData = 26,
    WebglReadBufferSubDataResponse = 27,
    InvalidateWheelEventListenerState = 28,
    AsyncScrollBy = 29,
    AsyncScrollByResponse = 30,
    ShouldDeferMainThreadPresentForAsyncScroll = 31,
    ShouldDeferMainThreadPresentForAsyncScrollResponse = 32,
    TakePendingAsyncScrollUpdates = 33,
    TakePendingAsyncScrollUpdatesResponse = 34,
    ViewportSizeUpdated = 35,
    PresentFrame = 36,
    RequestScreenshot = 37,
};

class InitTransportResponse final : public IPC::Message {
public:
    InitTransportResponse(int compositor_pid)
        : m_compositor_pid(move(compositor_pid))
    {
    }

    InitTransportResponse(InitTransportResponse const&) = default;
    InitTransportResponse(InitTransportResponse&&) = default;
    InitTransportResponse& operator=(InitTransportResponse const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, int>)
    InitTransportResponse(WrappedReturnType&& value)
        : m_compositor_pid(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::InitTransportResponse; }
    static i32 static_message_id() { return (int)MessageID::InitTransportResponse; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::InitTransportResponse"sv; }

    static ErrorOr<NonnullOwnPtr<InitTransportResponse>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto compositor_pid = TRY((decoder.decode<int>()));
        return make<InitTransportResponse>(move(compositor_pid));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(int compositor_pid)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::InitTransportResponse));
        TRY(stream.encode(compositor_pid));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_compositor_pid);
    }

    int compositor_pid() const { return m_compositor_pid; }

private:
    int m_compositor_pid;
};

class InitTransport final : public IPC::Message {
public:
    typedef class InitTransportResponse ResponseType;

    InitTransport(int peer_pid)
        : m_peer_pid(move(peer_pid))
    {
    }

    InitTransport(InitTransport const&) = default;
    InitTransport(InitTransport&&) = default;
    InitTransport& operator=(InitTransport const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, int>)
    InitTransport(WrappedReturnType&& value)
        : m_peer_pid(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::InitTransport; }
    static i32 static_message_id() { return (int)MessageID::InitTransport; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::InitTransport"sv; }

    static ErrorOr<NonnullOwnPtr<InitTransport>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto peer_pid = TRY((decoder.decode<int>()));
        return make<InitTransport>(move(peer_pid));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(int peer_pid)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::InitTransport));
        TRY(stream.encode(peer_pid));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_peer_pid);
    }

    int peer_pid() const { return m_peer_pid; }

private:
    int m_peer_pid;
};

class SetParentContext final : public IPC::Message {
public:
    SetParentContext(Web::Compositor::CompositorContextId context_id, Optional<Web::Compositor::CompositorContextId> parent_context_id)
        : m_context_id(move(context_id))
        , m_parent_context_id(move(parent_context_id))
    {
    }

    SetParentContext(SetParentContext const&) = default;
    SetParentContext(SetParentContext&&) = default;
    SetParentContext& operator=(SetParentContext const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::SetParentContext; }
    static i32 static_message_id() { return (int)MessageID::SetParentContext; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::SetParentContext"sv; }

    static ErrorOr<NonnullOwnPtr<SetParentContext>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        auto parent_context_id = TRY((decoder.decode<Optional<Web::Compositor::CompositorContextId>>()));
        return make<SetParentContext>(move(context_id), move(parent_context_id));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id, Optional<Web::Compositor::CompositorContextId> const& parent_context_id)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::SetParentContext));
        TRY(stream.encode(context_id));
        TRY(stream.encode(parent_context_id));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id, m_parent_context_id);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

    Optional<Web::Compositor::CompositorContextId> const& parent_context_id() const { return m_parent_context_id; }
    Optional<Web::Compositor::CompositorContextId> take_parent_context_id() { return move(m_parent_context_id); }

private:
    Web::Compositor::CompositorContextId m_context_id;
    Optional<Web::Compositor::CompositorContextId> m_parent_context_id;
};

class StopPresentingToClient final : public IPC::Message {
public:
    StopPresentingToClient(Web::Compositor::CompositorContextId context_id)
        : m_context_id(move(context_id))
    {
    }

    StopPresentingToClient(StopPresentingToClient const&) = default;
    StopPresentingToClient(StopPresentingToClient&&) = default;
    StopPresentingToClient& operator=(StopPresentingToClient const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, Web::Compositor::CompositorContextId>)
    StopPresentingToClient(WrappedReturnType&& value)
        : m_context_id(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::StopPresentingToClient; }
    static i32 static_message_id() { return (int)MessageID::StopPresentingToClient; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::StopPresentingToClient"sv; }

    static ErrorOr<NonnullOwnPtr<StopPresentingToClient>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        return make<StopPresentingToClient>(move(context_id));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::StopPresentingToClient));
        TRY(stream.encode(context_id));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

private:
    Web::Compositor::CompositorContextId m_context_id;
};

class DestroyContext final : public IPC::Message {
public:
    DestroyContext(Web::Compositor::CompositorContextId context_id)
        : m_context_id(move(context_id))
    {
    }

    DestroyContext(DestroyContext const&) = default;
    DestroyContext(DestroyContext&&) = default;
    DestroyContext& operator=(DestroyContext const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, Web::Compositor::CompositorContextId>)
    DestroyContext(WrappedReturnType&& value)
        : m_context_id(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::DestroyContext; }
    static i32 static_message_id() { return (int)MessageID::DestroyContext; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::DestroyContext"sv; }

    static ErrorOr<NonnullOwnPtr<DestroyContext>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        return make<DestroyContext>(move(context_id));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::DestroyContext));
        TRY(stream.encode(context_id));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

private:
    Web::Compositor::CompositorContextId m_context_id;
};

class UpdateDisplayList final : public IPC::Message {
public:
    UpdateDisplayList(Web::Compositor::CompositorContextId context_id, NonnullRefPtr<Web::Painting::DisplayList> display_list, Web::Painting::AccumulatedVisualContextTree visual_context_tree, Web::Painting::DisplayListResourceTransaction resource_transaction, Web::Painting::ScrollStateSnapshot scroll_state_snapshot)
        : m_context_id(move(context_id))
        , m_display_list(move(display_list))
        , m_visual_context_tree(move(visual_context_tree))
        , m_resource_transaction(move(resource_transaction))
        , m_scroll_state_snapshot(move(scroll_state_snapshot))
    {
    }

    UpdateDisplayList(UpdateDisplayList const&) = default;
    UpdateDisplayList(UpdateDisplayList&&) = default;
    UpdateDisplayList& operator=(UpdateDisplayList const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::UpdateDisplayList; }
    static i32 static_message_id() { return (int)MessageID::UpdateDisplayList; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::UpdateDisplayList"sv; }

    static ErrorOr<NonnullOwnPtr<UpdateDisplayList>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        auto display_list = TRY((decoder.decode<NonnullRefPtr<Web::Painting::DisplayList>>()));
        auto visual_context_tree = TRY((decoder.decode<Web::Painting::AccumulatedVisualContextTree>()));
        auto resource_transaction = TRY((decoder.decode<Web::Painting::DisplayListResourceTransaction>()));
        auto scroll_state_snapshot = TRY((decoder.decode<Web::Painting::ScrollStateSnapshot>()));
        return make<UpdateDisplayList>(move(context_id), move(display_list), move(visual_context_tree), move(resource_transaction), move(scroll_state_snapshot));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id, NonnullRefPtr<Web::Painting::DisplayList> const& display_list, Web::Painting::AccumulatedVisualContextTree const& visual_context_tree, Web::Painting::DisplayListResourceTransaction const& resource_transaction, Web::Painting::ScrollStateSnapshot const& scroll_state_snapshot)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::UpdateDisplayList));
        TRY(stream.encode(context_id));
        TRY(stream.encode(display_list));
        TRY(stream.encode(visual_context_tree));
        TRY(stream.encode(resource_transaction));
        TRY(stream.encode(scroll_state_snapshot));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id, m_display_list, m_visual_context_tree, m_resource_transaction, m_scroll_state_snapshot);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

    NonnullRefPtr<Web::Painting::DisplayList> const& display_list() const { return m_display_list; }
    NonnullRefPtr<Web::Painting::DisplayList> take_display_list() { return move(m_display_list); }

    Web::Painting::AccumulatedVisualContextTree const& visual_context_tree() const { return m_visual_context_tree; }
    Web::Painting::AccumulatedVisualContextTree take_visual_context_tree() { return move(m_visual_context_tree); }

    Web::Painting::DisplayListResourceTransaction const& resource_transaction() const { return m_resource_transaction; }
    Web::Painting::DisplayListResourceTransaction take_resource_transaction() { return move(m_resource_transaction); }

    Web::Painting::ScrollStateSnapshot const& scroll_state_snapshot() const { return m_scroll_state_snapshot; }
    Web::Painting::ScrollStateSnapshot take_scroll_state_snapshot() { return move(m_scroll_state_snapshot); }

private:
    Web::Compositor::CompositorContextId m_context_id;
    NonnullRefPtr<Web::Painting::DisplayList> m_display_list;
    Web::Painting::AccumulatedVisualContextTree m_visual_context_tree;
    Web::Painting::DisplayListResourceTransaction m_resource_transaction;
    Web::Painting::ScrollStateSnapshot m_scroll_state_snapshot;
};

class UpdateImageFrameResources final : public IPC::Message {
public:
    UpdateImageFrameResources(Web::Compositor::CompositorContextId context_id, Vector<Web::Painting::DisplayListImageFrameResource> image_frames)
        : m_context_id(move(context_id))
        , m_image_frames(move(image_frames))
    {
    }

    UpdateImageFrameResources(UpdateImageFrameResources const&) = default;
    UpdateImageFrameResources(UpdateImageFrameResources&&) = default;
    UpdateImageFrameResources& operator=(UpdateImageFrameResources const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::UpdateImageFrameResources; }
    static i32 static_message_id() { return (int)MessageID::UpdateImageFrameResources; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::UpdateImageFrameResources"sv; }

    static ErrorOr<NonnullOwnPtr<UpdateImageFrameResources>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        auto image_frames = TRY((decoder.decode<Vector<Web::Painting::DisplayListImageFrameResource>>()));
        return make<UpdateImageFrameResources>(move(context_id), move(image_frames));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id, ReadonlySpan<Web::Painting::DisplayListImageFrameResource> image_frames)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::UpdateImageFrameResources));
        TRY(stream.encode(context_id));
        TRY(stream.encode(image_frames));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id, m_image_frames);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

    Vector<Web::Painting::DisplayListImageFrameResource> const& image_frames() const { return m_image_frames; }
    Vector<Web::Painting::DisplayListImageFrameResource> take_image_frames() { return move(m_image_frames); }

private:
    Web::Compositor::CompositorContextId m_context_id;
    Vector<Web::Painting::DisplayListImageFrameResource> m_image_frames;
};

class UpdateVisualContextTree final : public IPC::Message {
public:
    UpdateVisualContextTree(Web::Compositor::CompositorContextId context_id, Web::Painting::AccumulatedVisualContextTree visual_context_tree)
        : m_context_id(move(context_id))
        , m_visual_context_tree(move(visual_context_tree))
    {
    }

    UpdateVisualContextTree(UpdateVisualContextTree const&) = default;
    UpdateVisualContextTree(UpdateVisualContextTree&&) = default;
    UpdateVisualContextTree& operator=(UpdateVisualContextTree const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::UpdateVisualContextTree; }
    static i32 static_message_id() { return (int)MessageID::UpdateVisualContextTree; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::UpdateVisualContextTree"sv; }

    static ErrorOr<NonnullOwnPtr<UpdateVisualContextTree>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        auto visual_context_tree = TRY((decoder.decode<Web::Painting::AccumulatedVisualContextTree>()));
        return make<UpdateVisualContextTree>(move(context_id), move(visual_context_tree));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id, Web::Painting::AccumulatedVisualContextTree const& visual_context_tree)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::UpdateVisualContextTree));
        TRY(stream.encode(context_id));
        TRY(stream.encode(visual_context_tree));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id, m_visual_context_tree);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

    Web::Painting::AccumulatedVisualContextTree const& visual_context_tree() const { return m_visual_context_tree; }
    Web::Painting::AccumulatedVisualContextTree take_visual_context_tree() { return move(m_visual_context_tree); }

private:
    Web::Compositor::CompositorContextId m_context_id;
    Web::Painting::AccumulatedVisualContextTree m_visual_context_tree;
};

class UpdateScrollState final : public IPC::Message {
public:
    UpdateScrollState(Web::Compositor::CompositorContextId context_id, Web::Painting::ScrollStateSnapshot scroll_state_snapshot)
        : m_context_id(move(context_id))
        , m_scroll_state_snapshot(move(scroll_state_snapshot))
    {
    }

    UpdateScrollState(UpdateScrollState const&) = default;
    UpdateScrollState(UpdateScrollState&&) = default;
    UpdateScrollState& operator=(UpdateScrollState const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::UpdateScrollState; }
    static i32 static_message_id() { return (int)MessageID::UpdateScrollState; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::UpdateScrollState"sv; }

    static ErrorOr<NonnullOwnPtr<UpdateScrollState>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        auto scroll_state_snapshot = TRY((decoder.decode<Web::Painting::ScrollStateSnapshot>()));
        return make<UpdateScrollState>(move(context_id), move(scroll_state_snapshot));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id, Web::Painting::ScrollStateSnapshot const& scroll_state_snapshot)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::UpdateScrollState));
        TRY(stream.encode(context_id));
        TRY(stream.encode(scroll_state_snapshot));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id, m_scroll_state_snapshot);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

    Web::Painting::ScrollStateSnapshot const& scroll_state_snapshot() const { return m_scroll_state_snapshot; }
    Web::Painting::ScrollStateSnapshot take_scroll_state_snapshot() { return move(m_scroll_state_snapshot); }

private:
    Web::Compositor::CompositorContextId m_context_id;
    Web::Painting::ScrollStateSnapshot m_scroll_state_snapshot;
};

class UpdateVideoFrame final : public IPC::Message {
public:
    UpdateVideoFrame(Web::Compositor::CompositorContextId context_id, Web::Painting::VideoFrameResourceId frame_id, NonnullRefPtr<Media::VideoFrame const> frame)
        : m_context_id(move(context_id))
        , m_frame_id(move(frame_id))
        , m_frame(move(frame))
    {
    }

    UpdateVideoFrame(UpdateVideoFrame const&) = default;
    UpdateVideoFrame(UpdateVideoFrame&&) = default;
    UpdateVideoFrame& operator=(UpdateVideoFrame const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::UpdateVideoFrame; }
    static i32 static_message_id() { return (int)MessageID::UpdateVideoFrame; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::UpdateVideoFrame"sv; }

    static ErrorOr<NonnullOwnPtr<UpdateVideoFrame>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        auto frame_id = TRY((decoder.decode<Web::Painting::VideoFrameResourceId>()));
        auto frame = TRY((decoder.decode<NonnullRefPtr<Media::VideoFrame const>>()));
        return make<UpdateVideoFrame>(move(context_id), move(frame_id), move(frame));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id, Web::Painting::VideoFrameResourceId const& frame_id, NonnullRefPtr<Media::VideoFrame const> const& frame)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::UpdateVideoFrame));
        TRY(stream.encode(context_id));
        TRY(stream.encode(frame_id));
        TRY(stream.encode(frame));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id, m_frame_id, m_frame);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

    Web::Painting::VideoFrameResourceId const& frame_id() const { return m_frame_id; }
    Web::Painting::VideoFrameResourceId take_frame_id() { return move(m_frame_id); }

    NonnullRefPtr<Media::VideoFrame const> const& frame() const { return m_frame; }
    NonnullRefPtr<Media::VideoFrame const> take_frame() { return move(m_frame); }

private:
    Web::Compositor::CompositorContextId m_context_id;
    Web::Painting::VideoFrameResourceId m_frame_id;
    NonnullRefPtr<Media::VideoFrame const> m_frame;
};

class ClearVideoFrame final : public IPC::Message {
public:
    ClearVideoFrame(Web::Compositor::CompositorContextId context_id, Web::Painting::VideoFrameResourceId frame_id)
        : m_context_id(move(context_id))
        , m_frame_id(move(frame_id))
    {
    }

    ClearVideoFrame(ClearVideoFrame const&) = default;
    ClearVideoFrame(ClearVideoFrame&&) = default;
    ClearVideoFrame& operator=(ClearVideoFrame const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::ClearVideoFrame; }
    static i32 static_message_id() { return (int)MessageID::ClearVideoFrame; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::ClearVideoFrame"sv; }

    static ErrorOr<NonnullOwnPtr<ClearVideoFrame>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        auto frame_id = TRY((decoder.decode<Web::Painting::VideoFrameResourceId>()));
        return make<ClearVideoFrame>(move(context_id), move(frame_id));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id, Web::Painting::VideoFrameResourceId const& frame_id)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::ClearVideoFrame));
        TRY(stream.encode(context_id));
        TRY(stream.encode(frame_id));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id, m_frame_id);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

    Web::Painting::VideoFrameResourceId const& frame_id() const { return m_frame_id; }
    Web::Painting::VideoFrameResourceId take_frame_id() { return move(m_frame_id); }

private:
    Web::Compositor::CompositorContextId m_context_id;
    Web::Painting::VideoFrameResourceId m_frame_id;
};

class CreateCanvas2dContextResponse final : public IPC::Message {
public:
    CreateCanvas2dContextResponse(bool success, Web::Painting::CanvasId canvas_id)
        : m_success(move(success))
        , m_canvas_id(move(canvas_id))
    {
    }

    CreateCanvas2dContextResponse(CreateCanvas2dContextResponse const&) = default;
    CreateCanvas2dContextResponse(CreateCanvas2dContextResponse&&) = default;
    CreateCanvas2dContextResponse& operator=(CreateCanvas2dContextResponse const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::CreateCanvas2dContextResponse; }
    static i32 static_message_id() { return (int)MessageID::CreateCanvas2dContextResponse; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::CreateCanvas2dContextResponse"sv; }

    static ErrorOr<NonnullOwnPtr<CreateCanvas2dContextResponse>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto success = TRY((decoder.decode<bool>()));
        auto canvas_id = TRY((decoder.decode<Web::Painting::CanvasId>()));
        return make<CreateCanvas2dContextResponse>(move(success), move(canvas_id));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(bool success, Web::Painting::CanvasId const& canvas_id)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::CreateCanvas2dContextResponse));
        TRY(stream.encode(success));
        TRY(stream.encode(canvas_id));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_success, m_canvas_id);
    }

    bool success() const { return m_success; }

    Web::Painting::CanvasId const& canvas_id() const { return m_canvas_id; }
    Web::Painting::CanvasId take_canvas_id() { return move(m_canvas_id); }

private:
    bool m_success;
    Web::Painting::CanvasId m_canvas_id;
};

class CreateCanvas2dContext final : public IPC::Message {
public:
    typedef class CreateCanvas2dContextResponse ResponseType;

    CreateCanvas2dContext(Gfx::IntSize size, bool alpha)
        : m_size(move(size))
        , m_alpha(move(alpha))
    {
    }

    CreateCanvas2dContext(CreateCanvas2dContext const&) = default;
    CreateCanvas2dContext(CreateCanvas2dContext&&) = default;
    CreateCanvas2dContext& operator=(CreateCanvas2dContext const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::CreateCanvas2dContext; }
    static i32 static_message_id() { return (int)MessageID::CreateCanvas2dContext; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::CreateCanvas2dContext"sv; }

    static ErrorOr<NonnullOwnPtr<CreateCanvas2dContext>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto size = TRY((decoder.decode<Gfx::IntSize>()));
        auto alpha = TRY((decoder.decode<bool>()));
        return make<CreateCanvas2dContext>(move(size), move(alpha));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Gfx::IntSize size, bool alpha)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::CreateCanvas2dContext));
        TRY(stream.encode(size));
        TRY(stream.encode(alpha));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_size, m_alpha);
    }

    Gfx::IntSize size() const { return m_size; }

    bool alpha() const { return m_alpha; }

private:
    Gfx::IntSize m_size;
    bool m_alpha;
};

class UpdateCanvas2dStream final : public IPC::Message {
public:
    UpdateCanvas2dStream(Vector<Web::Painting::Canvas2DCommandStreamSegment> segments)
        : m_segments(move(segments))
    {
    }

    UpdateCanvas2dStream(UpdateCanvas2dStream const&) = default;
    UpdateCanvas2dStream(UpdateCanvas2dStream&&) = default;
    UpdateCanvas2dStream& operator=(UpdateCanvas2dStream const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, Vector<Web::Painting::Canvas2DCommandStreamSegment>>)
    UpdateCanvas2dStream(WrappedReturnType&& value)
        : m_segments(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::UpdateCanvas2dStream; }
    static i32 static_message_id() { return (int)MessageID::UpdateCanvas2dStream; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::UpdateCanvas2dStream"sv; }

    static ErrorOr<NonnullOwnPtr<UpdateCanvas2dStream>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto segments = TRY((decoder.decode<Vector<Web::Painting::Canvas2DCommandStreamSegment>>()));
        return make<UpdateCanvas2dStream>(move(segments));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(ReadonlySpan<Web::Painting::Canvas2DCommandStreamSegment> segments)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::UpdateCanvas2dStream));
        TRY(stream.encode(segments));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_segments);
    }

    Vector<Web::Painting::Canvas2DCommandStreamSegment> const& segments() const { return m_segments; }
    Vector<Web::Painting::Canvas2DCommandStreamSegment> take_segments() { return move(m_segments); }

private:
    Vector<Web::Painting::Canvas2DCommandStreamSegment> m_segments;
};

class DestroyCanvasContext final : public IPC::Message {
public:
    DestroyCanvasContext(Web::Painting::CanvasId canvas_id)
        : m_canvas_id(move(canvas_id))
    {
    }

    DestroyCanvasContext(DestroyCanvasContext const&) = default;
    DestroyCanvasContext(DestroyCanvasContext&&) = default;
    DestroyCanvasContext& operator=(DestroyCanvasContext const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, Web::Painting::CanvasId>)
    DestroyCanvasContext(WrappedReturnType&& value)
        : m_canvas_id(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::DestroyCanvasContext; }
    static i32 static_message_id() { return (int)MessageID::DestroyCanvasContext; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::DestroyCanvasContext"sv; }

    static ErrorOr<NonnullOwnPtr<DestroyCanvasContext>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto canvas_id = TRY((decoder.decode<Web::Painting::CanvasId>()));
        return make<DestroyCanvasContext>(move(canvas_id));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Painting::CanvasId const& canvas_id)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::DestroyCanvasContext));
        TRY(stream.encode(canvas_id));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_canvas_id);
    }

    Web::Painting::CanvasId const& canvas_id() const { return m_canvas_id; }
    Web::Painting::CanvasId take_canvas_id() { return move(m_canvas_id); }

private:
    Web::Painting::CanvasId m_canvas_id;
};

class GetCanvasPixelsResponse final : public IPC::Message {
public:
    GetCanvasPixelsResponse(Gfx::ShareableBitmap pixels)
        : m_pixels(move(pixels))
    {
    }

    GetCanvasPixelsResponse(GetCanvasPixelsResponse const&) = default;
    GetCanvasPixelsResponse(GetCanvasPixelsResponse&&) = default;
    GetCanvasPixelsResponse& operator=(GetCanvasPixelsResponse const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, Gfx::ShareableBitmap>)
    GetCanvasPixelsResponse(WrappedReturnType&& value)
        : m_pixels(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::GetCanvasPixelsResponse; }
    static i32 static_message_id() { return (int)MessageID::GetCanvasPixelsResponse; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::GetCanvasPixelsResponse"sv; }

    static ErrorOr<NonnullOwnPtr<GetCanvasPixelsResponse>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto pixels = TRY((decoder.decode<Gfx::ShareableBitmap>()));
        return make<GetCanvasPixelsResponse>(move(pixels));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Gfx::ShareableBitmap const& pixels)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::GetCanvasPixelsResponse));
        TRY(stream.encode(pixels));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_pixels);
    }

    Gfx::ShareableBitmap const& pixels() const { return m_pixels; }
    Gfx::ShareableBitmap take_pixels() { return move(m_pixels); }

private:
    Gfx::ShareableBitmap m_pixels;
};

class GetCanvasPixels final : public IPC::Message {
public:
    typedef class GetCanvasPixelsResponse ResponseType;

    GetCanvasPixels(Web::Painting::CanvasId canvas_id, Gfx::IntRect rect)
        : m_canvas_id(move(canvas_id))
        , m_rect(move(rect))
    {
    }

    GetCanvasPixels(GetCanvasPixels const&) = default;
    GetCanvasPixels(GetCanvasPixels&&) = default;
    GetCanvasPixels& operator=(GetCanvasPixels const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::GetCanvasPixels; }
    static i32 static_message_id() { return (int)MessageID::GetCanvasPixels; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::GetCanvasPixels"sv; }

    static ErrorOr<NonnullOwnPtr<GetCanvasPixels>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto canvas_id = TRY((decoder.decode<Web::Painting::CanvasId>()));
        auto rect = TRY((decoder.decode<Gfx::IntRect>()));
        return make<GetCanvasPixels>(move(canvas_id), move(rect));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Painting::CanvasId const& canvas_id, Gfx::IntRect const& rect)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::GetCanvasPixels));
        TRY(stream.encode(canvas_id));
        TRY(stream.encode(rect));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_canvas_id, m_rect);
    }

    Web::Painting::CanvasId const& canvas_id() const { return m_canvas_id; }
    Web::Painting::CanvasId take_canvas_id() { return move(m_canvas_id); }

    Gfx::IntRect const& rect() const { return m_rect; }
    Gfx::IntRect take_rect() { return move(m_rect); }

private:
    Web::Painting::CanvasId m_canvas_id;
    Gfx::IntRect m_rect;
};

class CreateWebglContextResponse final : public IPC::Message {
public:
    CreateWebglContextResponse(bool success, Web::Painting::CanvasId canvas_id, Vector<String> supported_extensions)
        : m_success(move(success))
        , m_canvas_id(move(canvas_id))
        , m_supported_extensions(move(supported_extensions))
    {
    }

    CreateWebglContextResponse(CreateWebglContextResponse const&) = default;
    CreateWebglContextResponse(CreateWebglContextResponse&&) = default;
    CreateWebglContextResponse& operator=(CreateWebglContextResponse const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::CreateWebglContextResponse; }
    static i32 static_message_id() { return (int)MessageID::CreateWebglContextResponse; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::CreateWebglContextResponse"sv; }

    static ErrorOr<NonnullOwnPtr<CreateWebglContextResponse>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto success = TRY((decoder.decode<bool>()));
        auto canvas_id = TRY((decoder.decode<Web::Painting::CanvasId>()));
        auto supported_extensions = TRY((decoder.decode<Vector<String>>()));
        return make<CreateWebglContextResponse>(move(success), move(canvas_id), move(supported_extensions));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(bool success, Web::Painting::CanvasId const& canvas_id, ReadonlySpan<String> supported_extensions)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::CreateWebglContextResponse));
        TRY(stream.encode(success));
        TRY(stream.encode(canvas_id));
        TRY(stream.encode(supported_extensions));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_success, m_canvas_id, m_supported_extensions);
    }

    bool success() const { return m_success; }

    Web::Painting::CanvasId const& canvas_id() const { return m_canvas_id; }
    Web::Painting::CanvasId take_canvas_id() { return move(m_canvas_id); }

    Vector<String> const& supported_extensions() const { return m_supported_extensions; }
    Vector<String> take_supported_extensions() { return move(m_supported_extensions); }

private:
    bool m_success;
    Web::Painting::CanvasId m_canvas_id;
    Vector<String> m_supported_extensions;
};

class CreateWebglContext final : public IPC::Message {
public:
    typedef class CreateWebglContextResponse ResponseType;

    CreateWebglContext(Web::WebGL::WebGLVersion webgl_version, Gfx::IntSize size, bool depth, bool stencil, bool antialias)
        : m_webgl_version(move(webgl_version))
        , m_size(move(size))
        , m_depth(move(depth))
        , m_stencil(move(stencil))
        , m_antialias(move(antialias))
    {
    }

    CreateWebglContext(CreateWebglContext const&) = default;
    CreateWebglContext(CreateWebglContext&&) = default;
    CreateWebglContext& operator=(CreateWebglContext const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::CreateWebglContext; }
    static i32 static_message_id() { return (int)MessageID::CreateWebglContext; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::CreateWebglContext"sv; }

    static ErrorOr<NonnullOwnPtr<CreateWebglContext>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto webgl_version = TRY((decoder.decode<Web::WebGL::WebGLVersion>()));
        auto size = TRY((decoder.decode<Gfx::IntSize>()));
        auto depth = TRY((decoder.decode<bool>()));
        auto stencil = TRY((decoder.decode<bool>()));
        auto antialias = TRY((decoder.decode<bool>()));
        return make<CreateWebglContext>(move(webgl_version), move(size), move(depth), move(stencil), move(antialias));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::WebGL::WebGLVersion const& webgl_version, Gfx::IntSize size, bool depth, bool stencil, bool antialias)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::CreateWebglContext));
        TRY(stream.encode(webgl_version));
        TRY(stream.encode(size));
        TRY(stream.encode(depth));
        TRY(stream.encode(stencil));
        TRY(stream.encode(antialias));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_webgl_version, m_size, m_depth, m_stencil, m_antialias);
    }

    Web::WebGL::WebGLVersion const& webgl_version() const { return m_webgl_version; }
    Web::WebGL::WebGLVersion take_webgl_version() { return move(m_webgl_version); }

    Gfx::IntSize size() const { return m_size; }

    bool depth() const { return m_depth; }

    bool stencil() const { return m_stencil; }

    bool antialias() const { return m_antialias; }

private:
    Web::WebGL::WebGLVersion m_webgl_version;
    Gfx::IntSize m_size;
    bool m_depth;
    bool m_stencil;
    bool m_antialias;
};

class WebglCommands final : public IPC::Message {
public:
    WebglCommands(Web::Painting::CanvasId canvas_id, Core::AnonymousBuffer commands, Vector<Gfx::DecodedImageFrame> bitmaps)
        : m_canvas_id(move(canvas_id))
        , m_commands(move(commands))
        , m_bitmaps(move(bitmaps))
    {
    }

    WebglCommands(WebglCommands const&) = default;
    WebglCommands(WebglCommands&&) = default;
    WebglCommands& operator=(WebglCommands const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::WebglCommands; }
    static i32 static_message_id() { return (int)MessageID::WebglCommands; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::WebglCommands"sv; }

    static ErrorOr<NonnullOwnPtr<WebglCommands>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto canvas_id = TRY((decoder.decode<Web::Painting::CanvasId>()));
        auto commands = TRY((decoder.decode<Core::AnonymousBuffer>()));
        auto bitmaps = TRY((decoder.decode<Vector<Gfx::DecodedImageFrame>>()));
        return make<WebglCommands>(move(canvas_id), move(commands), move(bitmaps));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Painting::CanvasId const& canvas_id, Core::AnonymousBuffer const& commands, ReadonlySpan<Gfx::DecodedImageFrame> bitmaps)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::WebglCommands));
        TRY(stream.encode(canvas_id));
        TRY(stream.encode(commands));
        TRY(stream.encode(bitmaps));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_canvas_id, m_commands, m_bitmaps);
    }

    Web::Painting::CanvasId const& canvas_id() const { return m_canvas_id; }
    Web::Painting::CanvasId take_canvas_id() { return move(m_canvas_id); }

    Core::AnonymousBuffer const& commands() const { return m_commands; }
    Core::AnonymousBuffer take_commands() { return move(m_commands); }

    Vector<Gfx::DecodedImageFrame> const& bitmaps() const { return m_bitmaps; }
    Vector<Gfx::DecodedImageFrame> take_bitmaps() { return move(m_bitmaps); }

private:
    Web::Painting::CanvasId m_canvas_id;
    Core::AnonymousBuffer m_commands;
    Vector<Gfx::DecodedImageFrame> m_bitmaps;
};

class WebglPresentCanvas final : public IPC::Message {
public:
    WebglPresentCanvas(Web::Painting::CanvasId canvas_id, bool preserve_drawing_buffer)
        : m_canvas_id(move(canvas_id))
        , m_preserve_drawing_buffer(move(preserve_drawing_buffer))
    {
    }

    WebglPresentCanvas(WebglPresentCanvas const&) = default;
    WebglPresentCanvas(WebglPresentCanvas&&) = default;
    WebglPresentCanvas& operator=(WebglPresentCanvas const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::WebglPresentCanvas; }
    static i32 static_message_id() { return (int)MessageID::WebglPresentCanvas; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::WebglPresentCanvas"sv; }

    static ErrorOr<NonnullOwnPtr<WebglPresentCanvas>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto canvas_id = TRY((decoder.decode<Web::Painting::CanvasId>()));
        auto preserve_drawing_buffer = TRY((decoder.decode<bool>()));
        return make<WebglPresentCanvas>(move(canvas_id), move(preserve_drawing_buffer));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Painting::CanvasId const& canvas_id, bool preserve_drawing_buffer)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::WebglPresentCanvas));
        TRY(stream.encode(canvas_id));
        TRY(stream.encode(preserve_drawing_buffer));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_canvas_id, m_preserve_drawing_buffer);
    }

    Web::Painting::CanvasId const& canvas_id() const { return m_canvas_id; }
    Web::Painting::CanvasId take_canvas_id() { return move(m_canvas_id); }

    bool preserve_drawing_buffer() const { return m_preserve_drawing_buffer; }

private:
    Web::Painting::CanvasId m_canvas_id;
    bool m_preserve_drawing_buffer;
};

class WebglSyncCallResponse final : public IPC::Message {
public:
    WebglSyncCallResponse(ByteBuffer reply)
        : m_reply(move(reply))
    {
    }

    WebglSyncCallResponse(WebglSyncCallResponse const&) = default;
    WebglSyncCallResponse(WebglSyncCallResponse&&) = default;
    WebglSyncCallResponse& operator=(WebglSyncCallResponse const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, ByteBuffer>)
    WebglSyncCallResponse(WrappedReturnType&& value)
        : m_reply(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::WebglSyncCallResponse; }
    static i32 static_message_id() { return (int)MessageID::WebglSyncCallResponse; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::WebglSyncCallResponse"sv; }

    static ErrorOr<NonnullOwnPtr<WebglSyncCallResponse>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto reply = TRY((decoder.decode<ByteBuffer>()));
        return make<WebglSyncCallResponse>(move(reply));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(ReadonlyBytes reply)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::WebglSyncCallResponse));
        TRY(stream.encode(reply));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_reply);
    }

    ByteBuffer const& reply() const { return m_reply; }
    ByteBuffer take_reply() { return move(m_reply); }

private:
    ByteBuffer m_reply;
};

class WebglSyncCall final : public IPC::Message {
public:
    typedef class WebglSyncCallResponse ResponseType;

    WebglSyncCall(Web::Painting::CanvasId canvas_id, ByteBuffer request)
        : m_canvas_id(move(canvas_id))
        , m_request(move(request))
    {
    }

    WebglSyncCall(WebglSyncCall const&) = default;
    WebglSyncCall(WebglSyncCall&&) = default;
    WebglSyncCall& operator=(WebglSyncCall const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::WebglSyncCall; }
    static i32 static_message_id() { return (int)MessageID::WebglSyncCall; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::WebglSyncCall"sv; }

    static ErrorOr<NonnullOwnPtr<WebglSyncCall>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto canvas_id = TRY((decoder.decode<Web::Painting::CanvasId>()));
        auto request = TRY((decoder.decode<ByteBuffer>()));
        return make<WebglSyncCall>(move(canvas_id), move(request));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Painting::CanvasId const& canvas_id, ReadonlyBytes request)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::WebglSyncCall));
        TRY(stream.encode(canvas_id));
        TRY(stream.encode(request));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_canvas_id, m_request);
    }

    Web::Painting::CanvasId const& canvas_id() const { return m_canvas_id; }
    Web::Painting::CanvasId take_canvas_id() { return move(m_canvas_id); }

    ByteBuffer const& request() const { return m_request; }
    ByteBuffer take_request() { return move(m_request); }

private:
    Web::Painting::CanvasId m_canvas_id;
    ByteBuffer m_request;
};

class WebglReadPixelsResponse final : public IPC::Message {
public:
    WebglReadPixelsResponse(i32 length, i32 columns, i32 rows)
        : m_length(move(length))
        , m_columns(move(columns))
        , m_rows(move(rows))
    {
    }

    WebglReadPixelsResponse(WebglReadPixelsResponse const&) = default;
    WebglReadPixelsResponse(WebglReadPixelsResponse&&) = default;
    WebglReadPixelsResponse& operator=(WebglReadPixelsResponse const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::WebglReadPixelsResponse; }
    static i32 static_message_id() { return (int)MessageID::WebglReadPixelsResponse; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::WebglReadPixelsResponse"sv; }

    static ErrorOr<NonnullOwnPtr<WebglReadPixelsResponse>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto length = TRY((decoder.decode<i32>()));
        auto columns = TRY((decoder.decode<i32>()));
        auto rows = TRY((decoder.decode<i32>()));
        return make<WebglReadPixelsResponse>(move(length), move(columns), move(rows));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(i32 length, i32 columns, i32 rows)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::WebglReadPixelsResponse));
        TRY(stream.encode(length));
        TRY(stream.encode(columns));
        TRY(stream.encode(rows));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_length, m_columns, m_rows);
    }

    i32 length() const { return m_length; }

    i32 columns() const { return m_columns; }

    i32 rows() const { return m_rows; }

private:
    i32 m_length;
    i32 m_columns;
    i32 m_rows;
};

class WebglReadPixels final : public IPC::Message {
public:
    typedef class WebglReadPixelsResponse ResponseType;

    WebglReadPixels(Web::Painting::CanvasId canvas_id, i32 x, i32 y, i32 width, i32 height, u32 format, u32 type, i32 buf_size, Core::AnonymousBuffer pixels)
        : m_canvas_id(move(canvas_id))
        , m_x(move(x))
        , m_y(move(y))
        , m_width(move(width))
        , m_height(move(height))
        , m_format(move(format))
        , m_type(move(type))
        , m_buf_size(move(buf_size))
        , m_pixels(move(pixels))
    {
    }

    WebglReadPixels(WebglReadPixels const&) = default;
    WebglReadPixels(WebglReadPixels&&) = default;
    WebglReadPixels& operator=(WebglReadPixels const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::WebglReadPixels; }
    static i32 static_message_id() { return (int)MessageID::WebglReadPixels; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::WebglReadPixels"sv; }

    static ErrorOr<NonnullOwnPtr<WebglReadPixels>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto canvas_id = TRY((decoder.decode<Web::Painting::CanvasId>()));
        auto x = TRY((decoder.decode<i32>()));
        auto y = TRY((decoder.decode<i32>()));
        auto width = TRY((decoder.decode<i32>()));
        auto height = TRY((decoder.decode<i32>()));
        auto format = TRY((decoder.decode<u32>()));
        auto type = TRY((decoder.decode<u32>()));
        auto buf_size = TRY((decoder.decode<i32>()));
        auto pixels = TRY((decoder.decode<Core::AnonymousBuffer>()));
        return make<WebglReadPixels>(move(canvas_id), move(x), move(y), move(width), move(height), move(format), move(type), move(buf_size), move(pixels));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Painting::CanvasId const& canvas_id, i32 x, i32 y, i32 width, i32 height, u32 format, u32 type, i32 buf_size, Core::AnonymousBuffer const& pixels)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::WebglReadPixels));
        TRY(stream.encode(canvas_id));
        TRY(stream.encode(x));
        TRY(stream.encode(y));
        TRY(stream.encode(width));
        TRY(stream.encode(height));
        TRY(stream.encode(format));
        TRY(stream.encode(type));
        TRY(stream.encode(buf_size));
        TRY(stream.encode(pixels));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_canvas_id, m_x, m_y, m_width, m_height, m_format, m_type, m_buf_size, m_pixels);
    }

    Web::Painting::CanvasId const& canvas_id() const { return m_canvas_id; }
    Web::Painting::CanvasId take_canvas_id() { return move(m_canvas_id); }

    i32 x() const { return m_x; }

    i32 y() const { return m_y; }

    i32 width() const { return m_width; }

    i32 height() const { return m_height; }

    u32 format() const { return m_format; }

    u32 type() const { return m_type; }

    i32 buf_size() const { return m_buf_size; }

    Core::AnonymousBuffer const& pixels() const { return m_pixels; }
    Core::AnonymousBuffer take_pixels() { return move(m_pixels); }

private:
    Web::Painting::CanvasId m_canvas_id;
    i32 m_x;
    i32 m_y;
    i32 m_width;
    i32 m_height;
    u32 m_format;
    u32 m_type;
    i32 m_buf_size;
    Core::AnonymousBuffer m_pixels;
};

class WebglReadBufferSubDataResponse final : public IPC::Message {
public:
    WebglReadBufferSubDataResponse(bool success)
        : m_success(move(success))
    {
    }

    WebglReadBufferSubDataResponse(WebglReadBufferSubDataResponse const&) = default;
    WebglReadBufferSubDataResponse(WebglReadBufferSubDataResponse&&) = default;
    WebglReadBufferSubDataResponse& operator=(WebglReadBufferSubDataResponse const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, bool>)
    WebglReadBufferSubDataResponse(WrappedReturnType&& value)
        : m_success(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::WebglReadBufferSubDataResponse; }
    static i32 static_message_id() { return (int)MessageID::WebglReadBufferSubDataResponse; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::WebglReadBufferSubDataResponse"sv; }

    static ErrorOr<NonnullOwnPtr<WebglReadBufferSubDataResponse>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto success = TRY((decoder.decode<bool>()));
        return make<WebglReadBufferSubDataResponse>(move(success));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(bool success)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::WebglReadBufferSubDataResponse));
        TRY(stream.encode(success));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_success);
    }

    bool success() const { return m_success; }

private:
    bool m_success;
};

class WebglReadBufferSubData final : public IPC::Message {
public:
    typedef class WebglReadBufferSubDataResponse ResponseType;

    WebglReadBufferSubData(Web::Painting::CanvasId canvas_id, u32 target, i64 offset, i64 size, Core::AnonymousBuffer data)
        : m_canvas_id(move(canvas_id))
        , m_target(move(target))
        , m_offset(move(offset))
        , m_size(move(size))
        , m_data(move(data))
    {
    }

    WebglReadBufferSubData(WebglReadBufferSubData const&) = default;
    WebglReadBufferSubData(WebglReadBufferSubData&&) = default;
    WebglReadBufferSubData& operator=(WebglReadBufferSubData const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::WebglReadBufferSubData; }
    static i32 static_message_id() { return (int)MessageID::WebglReadBufferSubData; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::WebglReadBufferSubData"sv; }

    static ErrorOr<NonnullOwnPtr<WebglReadBufferSubData>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto canvas_id = TRY((decoder.decode<Web::Painting::CanvasId>()));
        auto target = TRY((decoder.decode<u32>()));
        auto offset = TRY((decoder.decode<i64>()));
        auto size = TRY((decoder.decode<i64>()));
        auto data = TRY((decoder.decode<Core::AnonymousBuffer>()));
        return make<WebglReadBufferSubData>(move(canvas_id), move(target), move(offset), move(size), move(data));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Painting::CanvasId const& canvas_id, u32 target, i64 offset, i64 size, Core::AnonymousBuffer const& data)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::WebglReadBufferSubData));
        TRY(stream.encode(canvas_id));
        TRY(stream.encode(target));
        TRY(stream.encode(offset));
        TRY(stream.encode(size));
        TRY(stream.encode(data));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_canvas_id, m_target, m_offset, m_size, m_data);
    }

    Web::Painting::CanvasId const& canvas_id() const { return m_canvas_id; }
    Web::Painting::CanvasId take_canvas_id() { return move(m_canvas_id); }

    u32 target() const { return m_target; }

    i64 offset() const { return m_offset; }

    i64 size() const { return m_size; }

    Core::AnonymousBuffer const& data() const { return m_data; }
    Core::AnonymousBuffer take_data() { return move(m_data); }

private:
    Web::Painting::CanvasId m_canvas_id;
    u32 m_target;
    i64 m_offset;
    i64 m_size;
    Core::AnonymousBuffer m_data;
};

class InvalidateWheelEventListenerState final : public IPC::Message {
public:
    InvalidateWheelEventListenerState(Web::Compositor::CompositorContextId context_id, u64 generation)
        : m_context_id(move(context_id))
        , m_generation(move(generation))
    {
    }

    InvalidateWheelEventListenerState(InvalidateWheelEventListenerState const&) = default;
    InvalidateWheelEventListenerState(InvalidateWheelEventListenerState&&) = default;
    InvalidateWheelEventListenerState& operator=(InvalidateWheelEventListenerState const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::InvalidateWheelEventListenerState; }
    static i32 static_message_id() { return (int)MessageID::InvalidateWheelEventListenerState; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::InvalidateWheelEventListenerState"sv; }

    static ErrorOr<NonnullOwnPtr<InvalidateWheelEventListenerState>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        auto generation = TRY((decoder.decode<u64>()));
        return make<InvalidateWheelEventListenerState>(move(context_id), move(generation));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id, u64 generation)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::InvalidateWheelEventListenerState));
        TRY(stream.encode(context_id));
        TRY(stream.encode(generation));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id, m_generation);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

    u64 generation() const { return m_generation; }

private:
    Web::Compositor::CompositorContextId m_context_id;
    u64 m_generation;
};

class AsyncScrollByResponse final : public IPC::Message {
public:
    AsyncScrollByResponse(Web::Compositor::AsyncScrollEnqueueResult result)
        : m_result(move(result))
    {
    }

    AsyncScrollByResponse(AsyncScrollByResponse const&) = default;
    AsyncScrollByResponse(AsyncScrollByResponse&&) = default;
    AsyncScrollByResponse& operator=(AsyncScrollByResponse const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, Web::Compositor::AsyncScrollEnqueueResult>)
    AsyncScrollByResponse(WrappedReturnType&& value)
        : m_result(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::AsyncScrollByResponse; }
    static i32 static_message_id() { return (int)MessageID::AsyncScrollByResponse; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::AsyncScrollByResponse"sv; }

    static ErrorOr<NonnullOwnPtr<AsyncScrollByResponse>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto result = TRY((decoder.decode<Web::Compositor::AsyncScrollEnqueueResult>()));
        return make<AsyncScrollByResponse>(move(result));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::AsyncScrollEnqueueResult const& result)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::AsyncScrollByResponse));
        TRY(stream.encode(result));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_result);
    }

    Web::Compositor::AsyncScrollEnqueueResult const& result() const { return m_result; }
    Web::Compositor::AsyncScrollEnqueueResult take_result() { return move(m_result); }

private:
    Web::Compositor::AsyncScrollEnqueueResult m_result;
};

class AsyncScrollBy final : public IPC::Message {
public:
    typedef class AsyncScrollByResponse ResponseType;

    AsyncScrollBy(Web::Compositor::CompositorContextId context_id, Web::UniqueNodeID document_id, Gfx::FloatPoint position, Gfx::FloatPoint delta, Gfx::IntRect viewport_rect, Web::Compositor::AsyncScrollOperationTracking operation_tracking)
        : m_context_id(move(context_id))
        , m_document_id(move(document_id))
        , m_position(move(position))
        , m_delta(move(delta))
        , m_viewport_rect(move(viewport_rect))
        , m_operation_tracking(move(operation_tracking))
    {
    }

    AsyncScrollBy(AsyncScrollBy const&) = default;
    AsyncScrollBy(AsyncScrollBy&&) = default;
    AsyncScrollBy& operator=(AsyncScrollBy const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::AsyncScrollBy; }
    static i32 static_message_id() { return (int)MessageID::AsyncScrollBy; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::AsyncScrollBy"sv; }

    static ErrorOr<NonnullOwnPtr<AsyncScrollBy>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        auto document_id = TRY((decoder.decode<Web::UniqueNodeID>()));
        auto position = TRY((decoder.decode<Gfx::FloatPoint>()));
        auto delta = TRY((decoder.decode<Gfx::FloatPoint>()));
        auto viewport_rect = TRY((decoder.decode<Gfx::IntRect>()));
        auto operation_tracking = TRY((decoder.decode<Web::Compositor::AsyncScrollOperationTracking>()));
        return make<AsyncScrollBy>(move(context_id), move(document_id), move(position), move(delta), move(viewport_rect), move(operation_tracking));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id, Web::UniqueNodeID const& document_id, Gfx::FloatPoint position, Gfx::FloatPoint delta, Gfx::IntRect const& viewport_rect, Web::Compositor::AsyncScrollOperationTracking const& operation_tracking)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::AsyncScrollBy));
        TRY(stream.encode(context_id));
        TRY(stream.encode(document_id));
        TRY(stream.encode(position));
        TRY(stream.encode(delta));
        TRY(stream.encode(viewport_rect));
        TRY(stream.encode(operation_tracking));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id, m_document_id, m_position, m_delta, m_viewport_rect, m_operation_tracking);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

    Web::UniqueNodeID const& document_id() const { return m_document_id; }
    Web::UniqueNodeID take_document_id() { return move(m_document_id); }

    Gfx::FloatPoint position() const { return m_position; }

    Gfx::FloatPoint delta() const { return m_delta; }

    Gfx::IntRect const& viewport_rect() const { return m_viewport_rect; }
    Gfx::IntRect take_viewport_rect() { return move(m_viewport_rect); }

    Web::Compositor::AsyncScrollOperationTracking const& operation_tracking() const { return m_operation_tracking; }
    Web::Compositor::AsyncScrollOperationTracking take_operation_tracking() { return move(m_operation_tracking); }

private:
    Web::Compositor::CompositorContextId m_context_id;
    Web::UniqueNodeID m_document_id;
    Gfx::FloatPoint m_position;
    Gfx::FloatPoint m_delta;
    Gfx::IntRect m_viewport_rect;
    Web::Compositor::AsyncScrollOperationTracking m_operation_tracking;
};

class ShouldDeferMainThreadPresentForAsyncScrollResponse final : public IPC::Message {
public:
    ShouldDeferMainThreadPresentForAsyncScrollResponse(bool should_defer)
        : m_should_defer(move(should_defer))
    {
    }

    ShouldDeferMainThreadPresentForAsyncScrollResponse(ShouldDeferMainThreadPresentForAsyncScrollResponse const&) = default;
    ShouldDeferMainThreadPresentForAsyncScrollResponse(ShouldDeferMainThreadPresentForAsyncScrollResponse&&) = default;
    ShouldDeferMainThreadPresentForAsyncScrollResponse& operator=(ShouldDeferMainThreadPresentForAsyncScrollResponse const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, bool>)
    ShouldDeferMainThreadPresentForAsyncScrollResponse(WrappedReturnType&& value)
        : m_should_defer(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::ShouldDeferMainThreadPresentForAsyncScrollResponse; }
    static i32 static_message_id() { return (int)MessageID::ShouldDeferMainThreadPresentForAsyncScrollResponse; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::ShouldDeferMainThreadPresentForAsyncScrollResponse"sv; }

    static ErrorOr<NonnullOwnPtr<ShouldDeferMainThreadPresentForAsyncScrollResponse>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto should_defer = TRY((decoder.decode<bool>()));
        return make<ShouldDeferMainThreadPresentForAsyncScrollResponse>(move(should_defer));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(bool should_defer)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::ShouldDeferMainThreadPresentForAsyncScrollResponse));
        TRY(stream.encode(should_defer));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_should_defer);
    }

    bool should_defer() const { return m_should_defer; }

private:
    bool m_should_defer;
};

class ShouldDeferMainThreadPresentForAsyncScroll final : public IPC::Message {
public:
    typedef class ShouldDeferMainThreadPresentForAsyncScrollResponse ResponseType;

    ShouldDeferMainThreadPresentForAsyncScroll(Web::Compositor::CompositorContextId context_id)
        : m_context_id(move(context_id))
    {
    }

    ShouldDeferMainThreadPresentForAsyncScroll(ShouldDeferMainThreadPresentForAsyncScroll const&) = default;
    ShouldDeferMainThreadPresentForAsyncScroll(ShouldDeferMainThreadPresentForAsyncScroll&&) = default;
    ShouldDeferMainThreadPresentForAsyncScroll& operator=(ShouldDeferMainThreadPresentForAsyncScroll const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, Web::Compositor::CompositorContextId>)
    ShouldDeferMainThreadPresentForAsyncScroll(WrappedReturnType&& value)
        : m_context_id(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::ShouldDeferMainThreadPresentForAsyncScroll; }
    static i32 static_message_id() { return (int)MessageID::ShouldDeferMainThreadPresentForAsyncScroll; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::ShouldDeferMainThreadPresentForAsyncScroll"sv; }

    static ErrorOr<NonnullOwnPtr<ShouldDeferMainThreadPresentForAsyncScroll>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        return make<ShouldDeferMainThreadPresentForAsyncScroll>(move(context_id));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::ShouldDeferMainThreadPresentForAsyncScroll));
        TRY(stream.encode(context_id));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

private:
    Web::Compositor::CompositorContextId m_context_id;
};

class TakePendingAsyncScrollUpdatesResponse final : public IPC::Message {
public:
    TakePendingAsyncScrollUpdatesResponse(Web::Compositor::PendingAsyncScrollUpdates updates)
        : m_updates(move(updates))
    {
    }

    TakePendingAsyncScrollUpdatesResponse(TakePendingAsyncScrollUpdatesResponse const&) = default;
    TakePendingAsyncScrollUpdatesResponse(TakePendingAsyncScrollUpdatesResponse&&) = default;
    TakePendingAsyncScrollUpdatesResponse& operator=(TakePendingAsyncScrollUpdatesResponse const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, Web::Compositor::PendingAsyncScrollUpdates>)
    TakePendingAsyncScrollUpdatesResponse(WrappedReturnType&& value)
        : m_updates(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::TakePendingAsyncScrollUpdatesResponse; }
    static i32 static_message_id() { return (int)MessageID::TakePendingAsyncScrollUpdatesResponse; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::TakePendingAsyncScrollUpdatesResponse"sv; }

    static ErrorOr<NonnullOwnPtr<TakePendingAsyncScrollUpdatesResponse>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto updates = TRY((decoder.decode<Web::Compositor::PendingAsyncScrollUpdates>()));
        return make<TakePendingAsyncScrollUpdatesResponse>(move(updates));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::PendingAsyncScrollUpdates const& updates)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::TakePendingAsyncScrollUpdatesResponse));
        TRY(stream.encode(updates));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_updates);
    }

    Web::Compositor::PendingAsyncScrollUpdates const& updates() const { return m_updates; }
    Web::Compositor::PendingAsyncScrollUpdates take_updates() { return move(m_updates); }

private:
    Web::Compositor::PendingAsyncScrollUpdates m_updates;
};

class TakePendingAsyncScrollUpdates final : public IPC::Message {
public:
    typedef class TakePendingAsyncScrollUpdatesResponse ResponseType;

    TakePendingAsyncScrollUpdates(Web::Compositor::CompositorContextId context_id)
        : m_context_id(move(context_id))
    {
    }

    TakePendingAsyncScrollUpdates(TakePendingAsyncScrollUpdates const&) = default;
    TakePendingAsyncScrollUpdates(TakePendingAsyncScrollUpdates&&) = default;
    TakePendingAsyncScrollUpdates& operator=(TakePendingAsyncScrollUpdates const&) = default;

    template<typename WrappedReturnType>
    requires(!SameAs<WrappedReturnType, Web::Compositor::CompositorContextId>)
    TakePendingAsyncScrollUpdates(WrappedReturnType&& value)
        : m_context_id(forward<WrappedReturnType>(value))
    {
    }

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::TakePendingAsyncScrollUpdates; }
    static i32 static_message_id() { return (int)MessageID::TakePendingAsyncScrollUpdates; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::TakePendingAsyncScrollUpdates"sv; }

    static ErrorOr<NonnullOwnPtr<TakePendingAsyncScrollUpdates>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        return make<TakePendingAsyncScrollUpdates>(move(context_id));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::TakePendingAsyncScrollUpdates));
        TRY(stream.encode(context_id));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

private:
    Web::Compositor::CompositorContextId m_context_id;
};

class ViewportSizeUpdated final : public IPC::Message {
public:
    ViewportSizeUpdated(Web::Compositor::CompositorContextId context_id, Gfx::IntSize viewport_size, Web::Compositor::WindowResizingInProgress window_resize_in_progress)
        : m_context_id(move(context_id))
        , m_viewport_size(move(viewport_size))
        , m_window_resize_in_progress(move(window_resize_in_progress))
    {
    }

    ViewportSizeUpdated(ViewportSizeUpdated const&) = default;
    ViewportSizeUpdated(ViewportSizeUpdated&&) = default;
    ViewportSizeUpdated& operator=(ViewportSizeUpdated const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::ViewportSizeUpdated; }
    static i32 static_message_id() { return (int)MessageID::ViewportSizeUpdated; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::ViewportSizeUpdated"sv; }

    static ErrorOr<NonnullOwnPtr<ViewportSizeUpdated>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        auto viewport_size = TRY((decoder.decode<Gfx::IntSize>()));
        auto window_resize_in_progress = TRY((decoder.decode<Web::Compositor::WindowResizingInProgress>()));
        return make<ViewportSizeUpdated>(move(context_id), move(viewport_size), move(window_resize_in_progress));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id, Gfx::IntSize viewport_size, Web::Compositor::WindowResizingInProgress const& window_resize_in_progress)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::ViewportSizeUpdated));
        TRY(stream.encode(context_id));
        TRY(stream.encode(viewport_size));
        TRY(stream.encode(window_resize_in_progress));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id, m_viewport_size, m_window_resize_in_progress);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

    Gfx::IntSize viewport_size() const { return m_viewport_size; }

    Web::Compositor::WindowResizingInProgress const& window_resize_in_progress() const { return m_window_resize_in_progress; }
    Web::Compositor::WindowResizingInProgress take_window_resize_in_progress() { return move(m_window_resize_in_progress); }

private:
    Web::Compositor::CompositorContextId m_context_id;
    Gfx::IntSize m_viewport_size;
    Web::Compositor::WindowResizingInProgress m_window_resize_in_progress;
};

class PresentFrame final : public IPC::Message {
public:
    PresentFrame(Web::Compositor::CompositorContextId context_id, Gfx::IntRect viewport_rect)
        : m_context_id(move(context_id))
        , m_viewport_rect(move(viewport_rect))
    {
    }

    PresentFrame(PresentFrame const&) = default;
    PresentFrame(PresentFrame&&) = default;
    PresentFrame& operator=(PresentFrame const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::PresentFrame; }
    static i32 static_message_id() { return (int)MessageID::PresentFrame; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::PresentFrame"sv; }

    static ErrorOr<NonnullOwnPtr<PresentFrame>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        auto viewport_rect = TRY((decoder.decode<Gfx::IntRect>()));
        return make<PresentFrame>(move(context_id), move(viewport_rect));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id, Gfx::IntRect const& viewport_rect)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::PresentFrame));
        TRY(stream.encode(context_id));
        TRY(stream.encode(viewport_rect));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id, m_viewport_rect);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

    Gfx::IntRect const& viewport_rect() const { return m_viewport_rect; }
    Gfx::IntRect take_viewport_rect() { return move(m_viewport_rect); }

private:
    Web::Compositor::CompositorContextId m_context_id;
    Gfx::IntRect m_viewport_rect;
};

class RequestScreenshot final : public IPC::Message {
public:
    RequestScreenshot(Web::Compositor::CompositorContextId context_id, Web::Compositor::ScreenshotRequestId request_id, Gfx::ShareableBitmap target_bitmap)
        : m_context_id(move(context_id))
        , m_request_id(move(request_id))
        , m_target_bitmap(move(target_bitmap))
    {
    }

    RequestScreenshot(RequestScreenshot const&) = default;
    RequestScreenshot(RequestScreenshot&&) = default;
    RequestScreenshot& operator=(RequestScreenshot const&) = default;

    static constexpr u32 ENDPOINT_MAGIC = 2583908703;

    virtual u32 endpoint_magic() const override { return ENDPOINT_MAGIC; }
    virtual i32 message_id() const override { return (int)MessageID::RequestScreenshot; }
    static i32 static_message_id() { return (int)MessageID::RequestScreenshot; }
    virtual StringView message_name() const override { return "CompositorWebContentServer::RequestScreenshot"sv; }

    static ErrorOr<NonnullOwnPtr<RequestScreenshot>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
    {
        IPC::Decoder decoder { stream, attachments };
        auto context_id = TRY((decoder.decode<Web::Compositor::CompositorContextId>()));
        auto request_id = TRY((decoder.decode<Web::Compositor::ScreenshotRequestId>()));
        auto target_bitmap = TRY((decoder.decode<Gfx::ShareableBitmap>()));
        return make<RequestScreenshot>(move(context_id), move(request_id), move(target_bitmap));
    }

    static ErrorOr<IPC::MessageBuffer> static_encode(Web::Compositor::CompositorContextId const& context_id, Web::Compositor::ScreenshotRequestId const& request_id, Gfx::ShareableBitmap const& target_bitmap)
    {
        IPC::MessageBuffer buffer;
        IPC::Encoder stream(buffer);
        TRY(stream.encode(ENDPOINT_MAGIC));
        TRY(stream.encode((int)MessageID::RequestScreenshot));
        TRY(stream.encode(context_id));
        TRY(stream.encode(request_id));
        TRY(stream.encode(target_bitmap));
        return buffer;
    }

    virtual ErrorOr<IPC::MessageBuffer> encode() const override
    {
        return static_encode(m_context_id, m_request_id, m_target_bitmap);
    }

    Web::Compositor::CompositorContextId const& context_id() const { return m_context_id; }
    Web::Compositor::CompositorContextId take_context_id() { return move(m_context_id); }

    Web::Compositor::ScreenshotRequestId const& request_id() const { return m_request_id; }
    Web::Compositor::ScreenshotRequestId take_request_id() { return move(m_request_id); }

    Gfx::ShareableBitmap const& target_bitmap() const { return m_target_bitmap; }
    Gfx::ShareableBitmap take_target_bitmap() { return move(m_target_bitmap); }

private:
    Web::Compositor::CompositorContextId m_context_id;
    Web::Compositor::ScreenshotRequestId m_request_id;
    Gfx::ShareableBitmap m_target_bitmap;
};

} // namespace Messages::CompositorWebContentServer

template<typename LocalEndpoint, typename PeerEndpoint>
class CompositorWebContentServerProxy {
public:
    // Used to disambiguate the constructor call.
    struct Tag { };

    CompositorWebContentServerProxy(IPC::Connection<LocalEndpoint, PeerEndpoint>& connection, Tag)
        : m_connection(connection)
    {
    }

    int init_transport(int peer_pid)
    {
        return m_connection.template send_sync<Messages::CompositorWebContentServer::InitTransport>(peer_pid)->compositor_pid();
    }

    void async_init_transport(int peer_pid)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::InitTransport::static_encode(peer_pid));
        (void)m_connection.post_message(message_buffer);
    }

    IPC::IPCErrorOr<int> try_init_transport(int peer_pid)
    {
        if (auto result = m_connection.template send_sync_but_allow_failure<Messages::CompositorWebContentServer::InitTransport>(peer_pid))
            return result->compositor_pid();
        m_connection.shutdown();
        return IPC::ErrorCode::PeerDisconnected;
    }

    void async_set_parent_context(Web::Compositor::CompositorContextId const& context_id, Optional<Web::Compositor::CompositorContextId> const& parent_context_id)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::SetParentContext::static_encode(move(context_id), move(parent_context_id)));
        (void)m_connection.post_message(message_buffer);
    }

    void async_stop_presenting_to_client(Web::Compositor::CompositorContextId const& context_id)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::StopPresentingToClient::static_encode(move(context_id)));
        (void)m_connection.post_message(message_buffer);
    }

    void async_destroy_context(Web::Compositor::CompositorContextId const& context_id)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::DestroyContext::static_encode(move(context_id)));
        (void)m_connection.post_message(message_buffer);
    }

    void async_update_display_list(Web::Compositor::CompositorContextId const& context_id, NonnullRefPtr<Web::Painting::DisplayList> const& display_list, Web::Painting::AccumulatedVisualContextTree const& visual_context_tree, Web::Painting::DisplayListResourceTransaction const& resource_transaction, Web::Painting::ScrollStateSnapshot const& scroll_state_snapshot)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::UpdateDisplayList::static_encode(move(context_id), move(display_list), move(visual_context_tree), move(resource_transaction), move(scroll_state_snapshot)));
        (void)m_connection.post_message(message_buffer);
    }

    void async_update_image_frame_resources(Web::Compositor::CompositorContextId const& context_id, ReadonlySpan<Web::Painting::DisplayListImageFrameResource> image_frames)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::UpdateImageFrameResources::static_encode(move(context_id), image_frames));
        (void)m_connection.post_message(message_buffer);
    }

    void async_update_visual_context_tree(Web::Compositor::CompositorContextId const& context_id, Web::Painting::AccumulatedVisualContextTree const& visual_context_tree)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::UpdateVisualContextTree::static_encode(move(context_id), move(visual_context_tree)));
        (void)m_connection.post_message(message_buffer);
    }

    void async_update_scroll_state(Web::Compositor::CompositorContextId const& context_id, Web::Painting::ScrollStateSnapshot const& scroll_state_snapshot)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::UpdateScrollState::static_encode(move(context_id), move(scroll_state_snapshot)));
        (void)m_connection.post_message(message_buffer);
    }

    void async_update_video_frame(Web::Compositor::CompositorContextId const& context_id, Web::Painting::VideoFrameResourceId const& frame_id, NonnullRefPtr<Media::VideoFrame const> const& frame)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::UpdateVideoFrame::static_encode(move(context_id), move(frame_id), move(frame)));
        (void)m_connection.post_message(message_buffer);
    }

    void async_clear_video_frame(Web::Compositor::CompositorContextId const& context_id, Web::Painting::VideoFrameResourceId const& frame_id)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::ClearVideoFrame::static_encode(move(context_id), move(frame_id)));
        (void)m_connection.post_message(message_buffer);
    }

    Messages::CompositorWebContentServer::CreateCanvas2dContextResponse create_canvas_2d_context(Gfx::IntSize size, bool alpha)
    {
        return move(*m_connection.template send_sync<Messages::CompositorWebContentServer::CreateCanvas2dContext>(size, alpha));
    }

    void async_create_canvas_2d_context(Gfx::IntSize size, bool alpha)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::CreateCanvas2dContext::static_encode(size, alpha));
        (void)m_connection.post_message(message_buffer);
    }

    IPC::IPCErrorOr<Messages::CompositorWebContentServer::CreateCanvas2dContextResponse> try_create_canvas_2d_context(Gfx::IntSize size, bool alpha)
    {
        if (auto result = m_connection.template send_sync_but_allow_failure<Messages::CompositorWebContentServer::CreateCanvas2dContext>(size, alpha))
            return move(*result);
        m_connection.shutdown();
        return IPC::ErrorCode::PeerDisconnected;
    }

    void async_update_canvas_2d_stream(ReadonlySpan<Web::Painting::Canvas2DCommandStreamSegment> segments)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::UpdateCanvas2dStream::static_encode(segments));
        (void)m_connection.post_message(message_buffer);
    }

    void async_destroy_canvas_context(Web::Painting::CanvasId const& canvas_id)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::DestroyCanvasContext::static_encode(move(canvas_id)));
        (void)m_connection.post_message(message_buffer);
    }

    Gfx::ShareableBitmap get_canvas_pixels(Web::Painting::CanvasId canvas_id, Gfx::IntRect rect)
    {
        return m_connection.template send_sync<Messages::CompositorWebContentServer::GetCanvasPixels>(move(canvas_id), move(rect))->take_pixels();
    }

    void async_get_canvas_pixels(Web::Painting::CanvasId const& canvas_id, Gfx::IntRect const& rect)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::GetCanvasPixels::static_encode(move(canvas_id), move(rect)));
        (void)m_connection.post_message(message_buffer);
    }

    IPC::IPCErrorOr<Gfx::ShareableBitmap> try_get_canvas_pixels(Web::Painting::CanvasId canvas_id, Gfx::IntRect rect)
    {
        if (auto result = m_connection.template send_sync_but_allow_failure<Messages::CompositorWebContentServer::GetCanvasPixels>(move(canvas_id), move(rect)))
            return result->take_pixels();
        m_connection.shutdown();
        return IPC::ErrorCode::PeerDisconnected;
    }

    Messages::CompositorWebContentServer::CreateWebglContextResponse create_webgl_context(Web::WebGL::WebGLVersion webgl_version, Gfx::IntSize size, bool depth, bool stencil, bool antialias)
    {
        return move(*m_connection.template send_sync<Messages::CompositorWebContentServer::CreateWebglContext>(move(webgl_version), size, depth, stencil, antialias));
    }

    void async_create_webgl_context(Web::WebGL::WebGLVersion const& webgl_version, Gfx::IntSize size, bool depth, bool stencil, bool antialias)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::CreateWebglContext::static_encode(move(webgl_version), size, depth, stencil, antialias));
        (void)m_connection.post_message(message_buffer);
    }

    IPC::IPCErrorOr<Messages::CompositorWebContentServer::CreateWebglContextResponse> try_create_webgl_context(Web::WebGL::WebGLVersion webgl_version, Gfx::IntSize size, bool depth, bool stencil, bool antialias)
    {
        if (auto result = m_connection.template send_sync_but_allow_failure<Messages::CompositorWebContentServer::CreateWebglContext>(move(webgl_version), size, depth, stencil, antialias))
            return move(*result);
        m_connection.shutdown();
        return IPC::ErrorCode::PeerDisconnected;
    }

    void async_webgl_commands(Web::Painting::CanvasId const& canvas_id, Core::AnonymousBuffer const& commands, ReadonlySpan<Gfx::DecodedImageFrame> bitmaps)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::WebglCommands::static_encode(move(canvas_id), move(commands), bitmaps));
        (void)m_connection.post_message(message_buffer);
    }

    void async_webgl_present_canvas(Web::Painting::CanvasId const& canvas_id, bool preserve_drawing_buffer)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::WebglPresentCanvas::static_encode(move(canvas_id), preserve_drawing_buffer));
        (void)m_connection.post_message(message_buffer);
    }

    ByteBuffer webgl_sync_call(Web::Painting::CanvasId canvas_id, ByteBuffer request)
    {
        return m_connection.template send_sync<Messages::CompositorWebContentServer::WebglSyncCall>(move(canvas_id), move(request))->take_reply();
    }

    void async_webgl_sync_call(Web::Painting::CanvasId const& canvas_id, ReadonlyBytes request)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::WebglSyncCall::static_encode(move(canvas_id), request));
        (void)m_connection.post_message(message_buffer);
    }

    IPC::IPCErrorOr<ByteBuffer> try_webgl_sync_call(Web::Painting::CanvasId canvas_id, ByteBuffer request)
    {
        if (auto result = m_connection.template send_sync_but_allow_failure<Messages::CompositorWebContentServer::WebglSyncCall>(move(canvas_id), move(request)))
            return result->take_reply();
        m_connection.shutdown();
        return IPC::ErrorCode::PeerDisconnected;
    }

    Messages::CompositorWebContentServer::WebglReadPixelsResponse webgl_read_pixels(Web::Painting::CanvasId canvas_id, i32 x, i32 y, i32 width, i32 height, u32 format, u32 type, i32 buf_size, Core::AnonymousBuffer pixels)
    {
        return move(*m_connection.template send_sync<Messages::CompositorWebContentServer::WebglReadPixels>(move(canvas_id), x, y, width, height, format, type, buf_size, move(pixels)));
    }

    void async_webgl_read_pixels(Web::Painting::CanvasId const& canvas_id, i32 x, i32 y, i32 width, i32 height, u32 format, u32 type, i32 buf_size, Core::AnonymousBuffer const& pixels)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::WebglReadPixels::static_encode(move(canvas_id), x, y, width, height, format, type, buf_size, move(pixels)));
        (void)m_connection.post_message(message_buffer);
    }

    IPC::IPCErrorOr<Messages::CompositorWebContentServer::WebglReadPixelsResponse> try_webgl_read_pixels(Web::Painting::CanvasId canvas_id, i32 x, i32 y, i32 width, i32 height, u32 format, u32 type, i32 buf_size, Core::AnonymousBuffer pixels)
    {
        if (auto result = m_connection.template send_sync_but_allow_failure<Messages::CompositorWebContentServer::WebglReadPixels>(move(canvas_id), x, y, width, height, format, type, buf_size, move(pixels)))
            return move(*result);
        m_connection.shutdown();
        return IPC::ErrorCode::PeerDisconnected;
    }

    bool webgl_read_buffer_sub_data(Web::Painting::CanvasId canvas_id, u32 target, i64 offset, i64 size, Core::AnonymousBuffer data)
    {
        return m_connection.template send_sync<Messages::CompositorWebContentServer::WebglReadBufferSubData>(move(canvas_id), target, offset, size, move(data))->success();
    }

    void async_webgl_read_buffer_sub_data(Web::Painting::CanvasId const& canvas_id, u32 target, i64 offset, i64 size, Core::AnonymousBuffer const& data)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::WebglReadBufferSubData::static_encode(move(canvas_id), target, offset, size, move(data)));
        (void)m_connection.post_message(message_buffer);
    }

    IPC::IPCErrorOr<bool> try_webgl_read_buffer_sub_data(Web::Painting::CanvasId canvas_id, u32 target, i64 offset, i64 size, Core::AnonymousBuffer data)
    {
        if (auto result = m_connection.template send_sync_but_allow_failure<Messages::CompositorWebContentServer::WebglReadBufferSubData>(move(canvas_id), target, offset, size, move(data)))
            return result->success();
        m_connection.shutdown();
        return IPC::ErrorCode::PeerDisconnected;
    }

    void async_invalidate_wheel_event_listener_state(Web::Compositor::CompositorContextId const& context_id, u64 generation)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::InvalidateWheelEventListenerState::static_encode(move(context_id), generation));
        (void)m_connection.post_message(message_buffer);
    }

    Web::Compositor::AsyncScrollEnqueueResult async_scroll_by(Web::Compositor::CompositorContextId context_id, Web::UniqueNodeID document_id, Gfx::FloatPoint position, Gfx::FloatPoint delta, Gfx::IntRect viewport_rect, Web::Compositor::AsyncScrollOperationTracking operation_tracking)
    {
        return m_connection.template send_sync<Messages::CompositorWebContentServer::AsyncScrollBy>(move(context_id), move(document_id), position, delta, move(viewport_rect), move(operation_tracking))->take_result();
    }

    void async_async_scroll_by(Web::Compositor::CompositorContextId const& context_id, Web::UniqueNodeID const& document_id, Gfx::FloatPoint position, Gfx::FloatPoint delta, Gfx::IntRect const& viewport_rect, Web::Compositor::AsyncScrollOperationTracking const& operation_tracking)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::AsyncScrollBy::static_encode(move(context_id), move(document_id), position, delta, move(viewport_rect), move(operation_tracking)));
        (void)m_connection.post_message(message_buffer);
    }

    IPC::IPCErrorOr<Web::Compositor::AsyncScrollEnqueueResult> try_async_scroll_by(Web::Compositor::CompositorContextId context_id, Web::UniqueNodeID document_id, Gfx::FloatPoint position, Gfx::FloatPoint delta, Gfx::IntRect viewport_rect, Web::Compositor::AsyncScrollOperationTracking operation_tracking)
    {
        if (auto result = m_connection.template send_sync_but_allow_failure<Messages::CompositorWebContentServer::AsyncScrollBy>(move(context_id), move(document_id), position, delta, move(viewport_rect), move(operation_tracking)))
            return result->take_result();
        m_connection.shutdown();
        return IPC::ErrorCode::PeerDisconnected;
    }

    bool should_defer_main_thread_present_for_async_scroll(Web::Compositor::CompositorContextId context_id)
    {
        return m_connection.template send_sync<Messages::CompositorWebContentServer::ShouldDeferMainThreadPresentForAsyncScroll>(move(context_id))->should_defer();
    }

    void async_should_defer_main_thread_present_for_async_scroll(Web::Compositor::CompositorContextId const& context_id)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::ShouldDeferMainThreadPresentForAsyncScroll::static_encode(move(context_id)));
        (void)m_connection.post_message(message_buffer);
    }

    IPC::IPCErrorOr<bool> try_should_defer_main_thread_present_for_async_scroll(Web::Compositor::CompositorContextId context_id)
    {
        if (auto result = m_connection.template send_sync_but_allow_failure<Messages::CompositorWebContentServer::ShouldDeferMainThreadPresentForAsyncScroll>(move(context_id)))
            return result->should_defer();
        m_connection.shutdown();
        return IPC::ErrorCode::PeerDisconnected;
    }

    Web::Compositor::PendingAsyncScrollUpdates take_pending_async_scroll_updates(Web::Compositor::CompositorContextId context_id)
    {
        return m_connection.template send_sync<Messages::CompositorWebContentServer::TakePendingAsyncScrollUpdates>(move(context_id))->take_updates();
    }

    void async_take_pending_async_scroll_updates(Web::Compositor::CompositorContextId const& context_id)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::TakePendingAsyncScrollUpdates::static_encode(move(context_id)));
        (void)m_connection.post_message(message_buffer);
    }

    IPC::IPCErrorOr<Web::Compositor::PendingAsyncScrollUpdates> try_take_pending_async_scroll_updates(Web::Compositor::CompositorContextId context_id)
    {
        if (auto result = m_connection.template send_sync_but_allow_failure<Messages::CompositorWebContentServer::TakePendingAsyncScrollUpdates>(move(context_id)))
            return result->take_updates();
        m_connection.shutdown();
        return IPC::ErrorCode::PeerDisconnected;
    }

    void async_viewport_size_updated(Web::Compositor::CompositorContextId const& context_id, Gfx::IntSize viewport_size, Web::Compositor::WindowResizingInProgress const& window_resize_in_progress)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::ViewportSizeUpdated::static_encode(move(context_id), viewport_size, move(window_resize_in_progress)));
        (void)m_connection.post_message(message_buffer);
    }

    void async_present_frame(Web::Compositor::CompositorContextId const& context_id, Gfx::IntRect const& viewport_rect)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::PresentFrame::static_encode(move(context_id), move(viewport_rect)));
        (void)m_connection.post_message(message_buffer);
    }

    void async_request_screenshot(Web::Compositor::CompositorContextId const& context_id, Web::Compositor::ScreenshotRequestId const& request_id, Gfx::ShareableBitmap const& target_bitmap)
    {
        auto message_buffer = MUST(Messages::CompositorWebContentServer::RequestScreenshot::static_encode(move(context_id), move(request_id), move(target_bitmap)));
        (void)m_connection.post_message(message_buffer);
    }

private:
    IPC::Connection<LocalEndpoint, PeerEndpoint>& m_connection;
};

template<typename LocalEndpoint, typename PeerEndpoint>
class CompositorWebContentServerProxy;
class CompositorWebContentServerStub;

class CompositorWebContentServerEndpoint {
public:
    template<typename LocalEndpoint>
    using Proxy = CompositorWebContentServerProxy<LocalEndpoint, CompositorWebContentServerEndpoint>;
    using Stub = CompositorWebContentServerStub;

    static u32 static_magic() { return 2583908703; }

    static ErrorOr<NonnullOwnPtr<IPC::Message>> decode_message(ReadonlyBytes buffer, [[maybe_unused]] Queue<IPC::Attachment>& attachments)
    {
        FixedMemoryStream stream { buffer };
        auto message_endpoint_magic = TRY(stream.read_value<u32>());

        if (message_endpoint_magic != static_magic())
            return Error::from_string_literal("Endpoint magic number mismatch, not my message!");

        auto message_id = TRY(stream.read_value<i32>());

        switch (message_id) {
        case (int)Messages::CompositorWebContentServer::MessageID::InitTransport:
            return Messages::CompositorWebContentServer::InitTransport::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::InitTransportResponse:
            return Messages::CompositorWebContentServer::InitTransportResponse::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::SetParentContext:
            return Messages::CompositorWebContentServer::SetParentContext::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::StopPresentingToClient:
            return Messages::CompositorWebContentServer::StopPresentingToClient::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::DestroyContext:
            return Messages::CompositorWebContentServer::DestroyContext::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::UpdateDisplayList:
            return Messages::CompositorWebContentServer::UpdateDisplayList::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::UpdateImageFrameResources:
            return Messages::CompositorWebContentServer::UpdateImageFrameResources::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::UpdateVisualContextTree:
            return Messages::CompositorWebContentServer::UpdateVisualContextTree::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::UpdateScrollState:
            return Messages::CompositorWebContentServer::UpdateScrollState::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::UpdateVideoFrame:
            return Messages::CompositorWebContentServer::UpdateVideoFrame::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::ClearVideoFrame:
            return Messages::CompositorWebContentServer::ClearVideoFrame::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::CreateCanvas2dContext:
            return Messages::CompositorWebContentServer::CreateCanvas2dContext::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::CreateCanvas2dContextResponse:
            return Messages::CompositorWebContentServer::CreateCanvas2dContextResponse::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::UpdateCanvas2dStream:
            return Messages::CompositorWebContentServer::UpdateCanvas2dStream::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::DestroyCanvasContext:
            return Messages::CompositorWebContentServer::DestroyCanvasContext::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::GetCanvasPixels:
            return Messages::CompositorWebContentServer::GetCanvasPixels::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::GetCanvasPixelsResponse:
            return Messages::CompositorWebContentServer::GetCanvasPixelsResponse::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::CreateWebglContext:
            return Messages::CompositorWebContentServer::CreateWebglContext::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::CreateWebglContextResponse:
            return Messages::CompositorWebContentServer::CreateWebglContextResponse::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglCommands:
            return Messages::CompositorWebContentServer::WebglCommands::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglPresentCanvas:
            return Messages::CompositorWebContentServer::WebglPresentCanvas::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglSyncCall:
            return Messages::CompositorWebContentServer::WebglSyncCall::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglSyncCallResponse:
            return Messages::CompositorWebContentServer::WebglSyncCallResponse::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglReadPixels:
            return Messages::CompositorWebContentServer::WebglReadPixels::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglReadPixelsResponse:
            return Messages::CompositorWebContentServer::WebglReadPixelsResponse::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglReadBufferSubData:
            return Messages::CompositorWebContentServer::WebglReadBufferSubData::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglReadBufferSubDataResponse:
            return Messages::CompositorWebContentServer::WebglReadBufferSubDataResponse::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::InvalidateWheelEventListenerState:
            return Messages::CompositorWebContentServer::InvalidateWheelEventListenerState::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::AsyncScrollBy:
            return Messages::CompositorWebContentServer::AsyncScrollBy::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::AsyncScrollByResponse:
            return Messages::CompositorWebContentServer::AsyncScrollByResponse::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::ShouldDeferMainThreadPresentForAsyncScroll:
            return Messages::CompositorWebContentServer::ShouldDeferMainThreadPresentForAsyncScroll::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::ShouldDeferMainThreadPresentForAsyncScrollResponse:
            return Messages::CompositorWebContentServer::ShouldDeferMainThreadPresentForAsyncScrollResponse::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::TakePendingAsyncScrollUpdates:
            return Messages::CompositorWebContentServer::TakePendingAsyncScrollUpdates::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::TakePendingAsyncScrollUpdatesResponse:
            return Messages::CompositorWebContentServer::TakePendingAsyncScrollUpdatesResponse::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::ViewportSizeUpdated:
            return Messages::CompositorWebContentServer::ViewportSizeUpdated::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::PresentFrame:
            return Messages::CompositorWebContentServer::PresentFrame::decode(stream, attachments);
        case (int)Messages::CompositorWebContentServer::MessageID::RequestScreenshot:
            return Messages::CompositorWebContentServer::RequestScreenshot::decode(stream, attachments);
        default:
            return Error::from_string_literal("Failed to decode CompositorWebContentServer message");
        }

        VERIFY_NOT_REACHED();
    }
};

class CompositorWebContentServerStub : public IPC::Stub {
public:
    CompositorWebContentServerStub() { }
    virtual ~CompositorWebContentServerStub() override { }

    virtual u32 magic() const override { return 2583908703; }
    virtual ByteString name() const override { return "CompositorWebContentServer"; }

    virtual ErrorOr<OwnPtr<IPC::MessageBuffer>> handle(NonnullOwnPtr<IPC::Message> message) override
    {
        switch (message->message_id()) {
        case (int)Messages::CompositorWebContentServer::MessageID::InitTransport:
            return handle_init_transport(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::SetParentContext:
            return handle_set_parent_context(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::StopPresentingToClient:
            return handle_stop_presenting_to_client(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::DestroyContext:
            return handle_destroy_context(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::UpdateDisplayList:
            return handle_update_display_list(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::UpdateImageFrameResources:
            return handle_update_image_frame_resources(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::UpdateVisualContextTree:
            return handle_update_visual_context_tree(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::UpdateScrollState:
            return handle_update_scroll_state(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::UpdateVideoFrame:
            return handle_update_video_frame(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::ClearVideoFrame:
            return handle_clear_video_frame(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::CreateCanvas2dContext:
            return handle_create_canvas_2d_context(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::UpdateCanvas2dStream:
            return handle_update_canvas_2d_stream(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::DestroyCanvasContext:
            return handle_destroy_canvas_context(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::GetCanvasPixels:
            return handle_get_canvas_pixels(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::CreateWebglContext:
            return handle_create_webgl_context(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglCommands:
            return handle_webgl_commands(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglPresentCanvas:
            return handle_webgl_present_canvas(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglSyncCall:
            return handle_webgl_sync_call(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglReadPixels:
            return handle_webgl_read_pixels(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::WebglReadBufferSubData:
            return handle_webgl_read_buffer_sub_data(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::InvalidateWheelEventListenerState:
            return handle_invalidate_wheel_event_listener_state(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::AsyncScrollBy:
            return handle_async_scroll_by(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::ShouldDeferMainThreadPresentForAsyncScroll:
            return handle_should_defer_main_thread_present_for_async_scroll(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::TakePendingAsyncScrollUpdates:
            return handle_take_pending_async_scroll_updates(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::ViewportSizeUpdated:
            return handle_viewport_size_updated(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::PresentFrame:
            return handle_present_frame(*message);
        case (int)Messages::CompositorWebContentServer::MessageID::RequestScreenshot:
            return handle_request_screenshot(*message);
        default:
            return Error::from_string_literal("Unknown message ID for CompositorWebContentServer endpoint");
        }
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_init_transport(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::InitTransport&>(message);
        auto response = init_transport(request.peer_pid());
        return make<IPC::MessageBuffer>(TRY(response.encode()));
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_set_parent_context(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::SetParentContext&>(message);
        set_parent_context(request.take_context_id(), request.take_parent_context_id());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_stop_presenting_to_client(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::StopPresentingToClient&>(message);
        stop_presenting_to_client(request.take_context_id());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_destroy_context(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::DestroyContext&>(message);
        destroy_context(request.take_context_id());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_update_display_list(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::UpdateDisplayList&>(message);
        update_display_list(request.take_context_id(), request.take_display_list(), request.take_visual_context_tree(), request.take_resource_transaction(), request.take_scroll_state_snapshot());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_update_image_frame_resources(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::UpdateImageFrameResources&>(message);
        update_image_frame_resources(request.take_context_id(), request.take_image_frames());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_update_visual_context_tree(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::UpdateVisualContextTree&>(message);
        update_visual_context_tree(request.take_context_id(), request.take_visual_context_tree());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_update_scroll_state(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::UpdateScrollState&>(message);
        update_scroll_state(request.take_context_id(), request.take_scroll_state_snapshot());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_update_video_frame(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::UpdateVideoFrame&>(message);
        update_video_frame(request.take_context_id(), request.take_frame_id(), request.take_frame());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_clear_video_frame(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::ClearVideoFrame&>(message);
        clear_video_frame(request.take_context_id(), request.take_frame_id());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_create_canvas_2d_context(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::CreateCanvas2dContext&>(message);
        auto response = create_canvas_2d_context(request.size(), request.alpha());
        return make<IPC::MessageBuffer>(TRY(response.encode()));
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_update_canvas_2d_stream(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::UpdateCanvas2dStream&>(message);
        update_canvas_2d_stream(request.take_segments());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_destroy_canvas_context(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::DestroyCanvasContext&>(message);
        destroy_canvas_context(request.take_canvas_id());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_get_canvas_pixels(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::GetCanvasPixels&>(message);
        auto response = get_canvas_pixels(request.take_canvas_id(), request.take_rect());
        return make<IPC::MessageBuffer>(TRY(response.encode()));
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_create_webgl_context(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::CreateWebglContext&>(message);
        auto response = create_webgl_context(request.take_webgl_version(), request.size(), request.depth(), request.stencil(), request.antialias());
        return make<IPC::MessageBuffer>(TRY(response.encode()));
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_webgl_commands(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::WebglCommands&>(message);
        webgl_commands(request.take_canvas_id(), request.take_commands(), request.take_bitmaps());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_webgl_present_canvas(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::WebglPresentCanvas&>(message);
        webgl_present_canvas(request.take_canvas_id(), request.preserve_drawing_buffer());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_webgl_sync_call(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::WebglSyncCall&>(message);
        auto response = webgl_sync_call(request.take_canvas_id(), request.take_request());
        return make<IPC::MessageBuffer>(TRY(response.encode()));
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_webgl_read_pixels(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::WebglReadPixels&>(message);
        auto response = webgl_read_pixels(request.take_canvas_id(), request.x(), request.y(), request.width(), request.height(), request.format(), request.type(), request.buf_size(), request.take_pixels());
        return make<IPC::MessageBuffer>(TRY(response.encode()));
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_webgl_read_buffer_sub_data(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::WebglReadBufferSubData&>(message);
        auto response = webgl_read_buffer_sub_data(request.take_canvas_id(), request.target(), request.offset(), request.size(), request.take_data());
        return make<IPC::MessageBuffer>(TRY(response.encode()));
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_invalidate_wheel_event_listener_state(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::InvalidateWheelEventListenerState&>(message);
        invalidate_wheel_event_listener_state(request.take_context_id(), request.generation());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_async_scroll_by(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::AsyncScrollBy&>(message);
        auto response = async_scroll_by(request.take_context_id(), request.take_document_id(), request.position(), request.delta(), request.take_viewport_rect(), request.take_operation_tracking());
        return make<IPC::MessageBuffer>(TRY(response.encode()));
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_should_defer_main_thread_present_for_async_scroll(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::ShouldDeferMainThreadPresentForAsyncScroll&>(message);
        auto response = should_defer_main_thread_present_for_async_scroll(request.take_context_id());
        return make<IPC::MessageBuffer>(TRY(response.encode()));
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_take_pending_async_scroll_updates(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::TakePendingAsyncScrollUpdates&>(message);
        auto response = take_pending_async_scroll_updates(request.take_context_id());
        return make<IPC::MessageBuffer>(TRY(response.encode()));
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_viewport_size_updated(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::ViewportSizeUpdated&>(message);
        viewport_size_updated(request.take_context_id(), request.viewport_size(), request.take_window_resize_in_progress());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_present_frame(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::PresentFrame&>(message);
        present_frame(request.take_context_id(), request.take_viewport_rect());
        return nullptr;
    }

    NEVER_INLINE ErrorOr<OwnPtr<IPC::MessageBuffer>> handle_request_screenshot(IPC::Message& message)
    {
        auto& request = static_cast<Messages::CompositorWebContentServer::RequestScreenshot&>(message);
        request_screenshot(request.take_context_id(), request.take_request_id(), request.take_target_bitmap());
        return nullptr;
    }

    virtual Messages::CompositorWebContentServer::InitTransportResponse init_transport(int peer_pid) = 0;
    virtual void set_parent_context(Web::Compositor::CompositorContextId context_id, Optional<Web::Compositor::CompositorContextId> parent_context_id) = 0;
    virtual void stop_presenting_to_client(Web::Compositor::CompositorContextId context_id) = 0;
    virtual void destroy_context(Web::Compositor::CompositorContextId context_id) = 0;
    virtual void update_display_list(Web::Compositor::CompositorContextId context_id, NonnullRefPtr<Web::Painting::DisplayList> display_list, Web::Painting::AccumulatedVisualContextTree visual_context_tree, Web::Painting::DisplayListResourceTransaction resource_transaction, Web::Painting::ScrollStateSnapshot scroll_state_snapshot) = 0;
    virtual void update_image_frame_resources(Web::Compositor::CompositorContextId context_id, Vector<Web::Painting::DisplayListImageFrameResource> image_frames) = 0;
    virtual void update_visual_context_tree(Web::Compositor::CompositorContextId context_id, Web::Painting::AccumulatedVisualContextTree visual_context_tree) = 0;
    virtual void update_scroll_state(Web::Compositor::CompositorContextId context_id, Web::Painting::ScrollStateSnapshot scroll_state_snapshot) = 0;
    virtual void update_video_frame(Web::Compositor::CompositorContextId context_id, Web::Painting::VideoFrameResourceId frame_id, NonnullRefPtr<Media::VideoFrame const> frame) = 0;
    virtual void clear_video_frame(Web::Compositor::CompositorContextId context_id, Web::Painting::VideoFrameResourceId frame_id) = 0;
    virtual Messages::CompositorWebContentServer::CreateCanvas2dContextResponse create_canvas_2d_context(Gfx::IntSize size, bool alpha) = 0;
    virtual void update_canvas_2d_stream(Vector<Web::Painting::Canvas2DCommandStreamSegment> segments) = 0;
    virtual void destroy_canvas_context(Web::Painting::CanvasId canvas_id) = 0;
    virtual Messages::CompositorWebContentServer::GetCanvasPixelsResponse get_canvas_pixels(Web::Painting::CanvasId canvas_id, Gfx::IntRect rect) = 0;
    virtual Messages::CompositorWebContentServer::CreateWebglContextResponse create_webgl_context(Web::WebGL::WebGLVersion webgl_version, Gfx::IntSize size, bool depth, bool stencil, bool antialias) = 0;
    virtual void webgl_commands(Web::Painting::CanvasId canvas_id, Core::AnonymousBuffer commands, Vector<Gfx::DecodedImageFrame> bitmaps) = 0;
    virtual void webgl_present_canvas(Web::Painting::CanvasId canvas_id, bool preserve_drawing_buffer) = 0;
    virtual Messages::CompositorWebContentServer::WebglSyncCallResponse webgl_sync_call(Web::Painting::CanvasId canvas_id, ByteBuffer request) = 0;
    virtual Messages::CompositorWebContentServer::WebglReadPixelsResponse webgl_read_pixels(Web::Painting::CanvasId canvas_id, i32 x, i32 y, i32 width, i32 height, u32 format, u32 type, i32 buf_size, Core::AnonymousBuffer pixels) = 0;
    virtual Messages::CompositorWebContentServer::WebglReadBufferSubDataResponse webgl_read_buffer_sub_data(Web::Painting::CanvasId canvas_id, u32 target, i64 offset, i64 size, Core::AnonymousBuffer data) = 0;
    virtual void invalidate_wheel_event_listener_state(Web::Compositor::CompositorContextId context_id, u64 generation) = 0;
    virtual Messages::CompositorWebContentServer::AsyncScrollByResponse async_scroll_by(Web::Compositor::CompositorContextId context_id, Web::UniqueNodeID document_id, Gfx::FloatPoint position, Gfx::FloatPoint delta, Gfx::IntRect viewport_rect, Web::Compositor::AsyncScrollOperationTracking operation_tracking) = 0;
    virtual Messages::CompositorWebContentServer::ShouldDeferMainThreadPresentForAsyncScrollResponse should_defer_main_thread_present_for_async_scroll(Web::Compositor::CompositorContextId context_id) = 0;
    virtual Messages::CompositorWebContentServer::TakePendingAsyncScrollUpdatesResponse take_pending_async_scroll_updates(Web::Compositor::CompositorContextId context_id) = 0;
    virtual void viewport_size_updated(Web::Compositor::CompositorContextId context_id, Gfx::IntSize viewport_size, Web::Compositor::WindowResizingInProgress window_resize_in_progress) = 0;
    virtual void present_frame(Web::Compositor::CompositorContextId context_id, Gfx::IntRect viewport_rect) = 0;
    virtual void request_screenshot(Web::Compositor::CompositorContextId context_id, Web::Compositor::ScreenshotRequestId request_id, Gfx::ShareableBitmap target_bitmap) = 0;
};

#if defined(AK_COMPILER_CLANG)
#pragma clang diagnostic pop
#endif
