/* * Copyright (c) 2026, Aliaksandr Kalenik * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Web::WebGL { class WEB_API WebGLContextProxyBase { AK_MAKE_NONCOPYABLE(WebGLContextProxyBase); AK_MAKE_NONMOVABLE(WebGLContextProxyBase); public: WebGLContextProxyBase(NonnullRefPtr, WebGLVersion, Vector supported_extensions); ~WebGLContextProxyBase(); void flush_commands(); Optional canvas_id() const { return m_transport->canvas_id(); } void make_current() { } void notify_content_will_change() { } u32 default_framebuffer() const { return 0; } u32 default_renderbuffer() const { return 0; } WebGLVersion webgl_version() const { return m_webgl_version; } Vector const& get_supported_opengl_extensions() const { return m_supported_extensions; } void set_size(Gfx::IntSize const&); void present_canvas_for_compositing(bool preserve_drawing_buffer); RefPtr read_back_drawing_buffer(Gfx::IntRect const&); void read_pixels_into_pixel_pack_buffer(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, long long offset); void read_buffer_sub_data(GLenum target, long long offset, Bytes destination); void tex_image2d_from_bitmap(GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type, Gfx::DecodedImageFrame, Optional destination_size, bool flip_y, bool premultiply_alpha); void tex_sub_image2d_from_bitmap(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, Gfx::DecodedImageFrame, Optional destination_size, bool flip_y, bool premultiply_alpha); GLenum take_pending_local_error() { auto error = m_pending_local_error; m_pending_local_error = 0; return error; } protected: static constexpr size_t max_pending_command_bytes = 4 * MiB; WebGLObjectId allocate_object_id() { return m_next_object_id++; } void set_pending_local_error(GLenum error) { if (m_pending_local_error == 0) m_pending_local_error = error; } ReadPixelsResult read_pixels_robust_angle_into_shared_buffer(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei buf_size, Core::AnonymousBuffer const& pixels); template void record(Command const& command, ReadonlyBytes inline_data = {}) { if (m_lost) return; m_commands.append(command, inline_data); if (m_commands.size_in_bytes() >= max_pending_command_bytes) flush_commands(); } ByteBuffer send_sync_call(ByteBuffer request); bool is_lost() const { return m_lost; } HashMap> m_string_cache; private: NonnullRefPtr m_transport; WebGLVersion m_webgl_version { WebGLVersion::WebGL1 }; Vector m_supported_extensions; WebGLCommandList m_commands; Vector m_pending_bitmaps; u32 m_next_object_id { 1 }; bool m_lost { false }; GLenum m_pending_local_error { 0 }; }; }