diff options
author | Luke Wilde <lukew@serenityos.org> | 2022-06-04 04:22:42 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-06-13 21:45:27 +0100 |
commit | 58f882200cfaa6f666876f728e1dd82a2352dfe3 (patch) | |
tree | ff8ce2ead18a2e63fe51a971860bb9078ce42016 | |
parent | b0c2aee2e4d7e38913259a2fb6fc024db9a12718 (diff) | |
download | serenity-58f882200cfaa6f666876f728e1dd82a2352dfe3.zip |
LibWeb: Add the ability to retrieve a WebGL context from getContext
19 files changed, 903 insertions, 21 deletions
diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index 410378c7e7..8d4de9054c 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -500,7 +500,7 @@ if (BUILD_LAGOM) lagom_lib(Web web SOURCES ${LIBWEB_SOURCES} ${LIBWEB_SUBDIR_SOURCES} ${LIBWEB_SUBSUBDIR_SOURCES} ${LIBWEB_GENERATED_SOURCES} - LIBS LagomMarkdown LagomGemini LagomGfx LagomJS LagomTextCodec LagomWasm LagomXML + LIBS LagomMarkdown LagomGemini LagomGfx LagomGL LagomJS LagomTextCodec LagomWasm LagomXML ) generate_js_wrappers(LagomWeb) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp index 1d5fd43c74..389344d8cb 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp @@ -48,6 +48,10 @@ static bool is_wrappable_type(Type const& type) return true; if (type.name == "AbortSignal") return true; + if (type.name == "CanvasRenderingContext2D") + return true; + if (type.name == "WebGLRenderingContext") + return true; return false; } diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h b/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h index 83e47af739..5968c8ae5b 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h +++ b/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h @@ -341,6 +341,8 @@ #include <LibWeb/Bindings/URLSearchParamsPrototype.h> #include <LibWeb/Bindings/WebGLContextEventConstructor.h> #include <LibWeb/Bindings/WebGLContextEventPrototype.h> +#include <LibWeb/Bindings/WebGLRenderingContextConstructor.h> +#include <LibWeb/Bindings/WebGLRenderingContextPrototype.h> #include <LibWeb/Bindings/WebSocketConstructor.h> #include <LibWeb/Bindings/WebSocketPrototype.h> #include <LibWeb/Bindings/WindowConstructor.h> @@ -529,6 +531,7 @@ ADD_WINDOW_OBJECT_INTERFACE(URLSearchParams) \ ADD_WINDOW_OBJECT_INTERFACE(URL) \ ADD_WINDOW_OBJECT_INTERFACE(WebGLContextEvent) \ + ADD_WINDOW_OBJECT_INTERFACE(WebGLRenderingContext) \ ADD_WINDOW_OBJECT_INTERFACE(WebSocket) \ ADD_WINDOW_OBJECT_INTERFACE(Worker) \ ADD_WINDOW_OBJECT_INTERFACE(XMLHttpRequest) \ diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 9e10768eef..b86615ba18 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -352,6 +352,9 @@ set(SOURCES WebAssembly/WebAssemblyTableConstructor.cpp WebAssembly/WebAssemblyTableObject.cpp WebAssembly/WebAssemblyTablePrototype.cpp + WebGL/WebGLContextAttributes.cpp + WebGL/WebGLRenderingContext.cpp + WebGL/WebGLRenderingContextBase.cpp WebSockets/WebSocket.cpp XHR/EventNames.cpp XHR/XMLHttpRequest.cpp @@ -372,7 +375,9 @@ set(GENERATED_SOURCES ) serenity_lib(LibWeb web) -target_link_libraries(LibWeb LibCore LibJS LibMarkdown LibGemini LibGUI LibGfx LibTextCodec LibWasm LibXML) + +# NOTE: We link with LibSoftGPU here instead of lazy loading it via dlopen() so that we do not have to unveil the library and pledge prot_exec. +target_link_libraries(LibWeb LibCore LibJS LibMarkdown LibGemini LibGL LibGUI LibGfx LibSoftGPU LibTextCodec LibWasm LibXML) link_with_unicode_data(LibWeb) generate_js_wrappers(LibWeb) diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 58617d8829..d125df9938 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -379,6 +379,8 @@ class ResourceLoader; namespace Web::WebGL { class WebGLContextEvent; +class WebGLRenderingContext; +class WebGLRenderingContextBase; } namespace Web::XHR { @@ -581,6 +583,7 @@ class URLSearchParamsPrototype; class URLSearchParamsWrapper; class URLWrapper; class WebGLContextEventWrapper; +class WebGLRenderingContextWrapper; class WebSocketWrapper; class WindowObject; class WindowProxy; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp index 413541378f..852dffe6b0 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp @@ -35,20 +35,32 @@ unsigned HTMLCanvasElement::height() const return attribute(HTML::AttributeNames::height).to_uint().value_or(150); } +void HTMLCanvasElement::reset_context_to_default_state() +{ + m_context.visit( + [](NonnullRefPtr<CanvasRenderingContext2D>& context) { + context->reset_to_default_state(); + }, + [](NonnullRefPtr<WebGL::WebGLRenderingContext>&) { + TODO(); + }, + [](Empty) { + // Do nothing. + }); +} + void HTMLCanvasElement::set_width(unsigned value) { set_attribute(HTML::AttributeNames::width, String::number(value)); m_bitmap = nullptr; - if (m_context) - m_context->reset_to_default_state(); + reset_context_to_default_state(); } void HTMLCanvasElement::set_height(unsigned value) { set_attribute(HTML::AttributeNames::height, String::number(value)); m_bitmap = nullptr; - if (m_context) - m_context->reset_to_default_state(); + reset_context_to_default_state(); } RefPtr<Layout::Node> HTMLCanvasElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties> style) @@ -56,19 +68,62 @@ RefPtr<Layout::Node> HTMLCanvasElement::create_layout_node(NonnullRefPtr<CSS::St return adopt_ref(*new Layout::CanvasBox(document(), *this, move(style))); } -CanvasRenderingContext2D* HTMLCanvasElement::get_context(String type) +HTMLCanvasElement::HasOrCreatedContext HTMLCanvasElement::create_2d_context() +{ + if (!m_context.has<Empty>()) + return m_context.has<NonnullRefPtr<CanvasRenderingContext2D>>() ? HasOrCreatedContext::Yes : HasOrCreatedContext::No; + + m_context = CanvasRenderingContext2D::create(*this); + return HasOrCreatedContext::Yes; +} + +JS::ThrowCompletionOr<HTMLCanvasElement::HasOrCreatedContext> HTMLCanvasElement::create_webgl_context(JS::Value options) { - if (type != "2d") - return nullptr; - if (!m_context) - m_context = CanvasRenderingContext2D::create(*this); - return m_context; + if (!m_context.has<Empty>()) + return m_context.has<NonnullRefPtr<WebGL::WebGLRenderingContext>>() ? HasOrCreatedContext::Yes : HasOrCreatedContext::No; + + auto maybe_context = TRY(WebGL::WebGLRenderingContext::create(*this, options)); + if (!maybe_context) + return HasOrCreatedContext::No; + + m_context = maybe_context.release_nonnull(); + return HasOrCreatedContext::Yes; } -static Gfx::IntSize bitmap_size_for_canvas(HTMLCanvasElement const& canvas) +// https://html.spec.whatwg.org/multipage/canvas.html#dom-canvas-getcontext +JS::ThrowCompletionOr<HTMLCanvasElement::RenderingContext> HTMLCanvasElement::get_context(String const& type, JS::Value options) { - auto width = canvas.width(); - auto height = canvas.height(); + // 1. If options is not an object, then set options to null. + if (!options.is_object()) + options = JS::js_null(); + + // 2. Set options to the result of converting options to a JavaScript value. + // NOTE: No-op. + + // 3. Run the steps in the cell of the following table whose column header matches this canvas element's canvas context mode and whose row header matches contextId: + // NOTE: See the spec for the full table. + if (type == "2d"sv) { + if (create_2d_context() == HasOrCreatedContext::Yes) + return m_context; + + return Empty {}; + } + + // NOTE: The WebGL spec says "experimental-webgl" is also acceptable and must be equivalent to "webgl". Other engines accept this, so we do too. + if (type.is_one_of("webgl"sv, "experimental-webgl"sv)) { + if (TRY(create_webgl_context(options)) == HasOrCreatedContext::Yes) + return m_context; + + return Empty {}; + } + + return Empty {}; +} + +static Gfx::IntSize bitmap_size_for_canvas(HTMLCanvasElement const& canvas, size_t minimum_width, size_t minimum_height) +{ + auto width = max(canvas.width(), minimum_width); + auto height = max(canvas.height(), minimum_height); Checked<size_t> area = width; area *= height; @@ -84,9 +139,9 @@ static Gfx::IntSize bitmap_size_for_canvas(HTMLCanvasElement const& canvas) return Gfx::IntSize(width, height); } -bool HTMLCanvasElement::create_bitmap() +bool HTMLCanvasElement::create_bitmap(size_t minimum_width, size_t minimum_height) { - auto size = bitmap_size_for_canvas(*this); + auto size = bitmap_size_for_canvas(*this, minimum_width, minimum_height); if (size.is_empty()) { m_bitmap = nullptr; return false; @@ -110,4 +165,18 @@ String HTMLCanvasElement::to_data_url(String const& type, [[maybe_unused]] Optio return AK::URL::create_with_data(type, encode_base64(encoded_bitmap), true).to_string(); } +void HTMLCanvasElement::present() +{ + m_context.visit( + [](NonnullRefPtr<CanvasRenderingContext2D>&) { + // Do nothing, CRC2D writes directly to the canvas bitmap. + }, + [](NonnullRefPtr<WebGL::WebGLRenderingContext>& context) { + context->present(); + }, + [](Empty) { + // Do nothing. + }); +} + } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.h b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.h index b6bda5884c..8da131068d 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.h @@ -9,21 +9,23 @@ #include <AK/ByteBuffer.h> #include <LibGfx/Forward.h> #include <LibWeb/HTML/HTMLElement.h> +#include <LibWeb/WebGL/WebGLRenderingContext.h> namespace Web::HTML { class HTMLCanvasElement final : public HTMLElement { public: using WrapperType = Bindings::HTMLCanvasElementWrapper; + using RenderingContext = Variant<NonnullRefPtr<CanvasRenderingContext2D>, NonnullRefPtr<WebGL::WebGLRenderingContext>, Empty>; HTMLCanvasElement(DOM::Document&, DOM::QualifiedName); virtual ~HTMLCanvasElement() override; Gfx::Bitmap const* bitmap() const { return m_bitmap; } Gfx::Bitmap* bitmap() { return m_bitmap; } - bool create_bitmap(); + bool create_bitmap(size_t minimum_width = 0, size_t minimum_height = 0); - CanvasRenderingContext2D* get_context(String type); + JS::ThrowCompletionOr<RenderingContext> get_context(String const& type, JS::Value options); unsigned width() const; unsigned height() const; @@ -33,11 +35,22 @@ public: String to_data_url(String const& type, Optional<double> quality) const; + void present(); + private: virtual RefPtr<Layout::Node> create_layout_node(NonnullRefPtr<CSS::StyleProperties>) override; + enum class HasOrCreatedContext { + No, + Yes, + }; + + HasOrCreatedContext create_2d_context(); + JS::ThrowCompletionOr<HasOrCreatedContext> create_webgl_context(JS::Value options); + void reset_context_to_default_state(); + RefPtr<Gfx::Bitmap> m_bitmap; - RefPtr<CanvasRenderingContext2D> m_context; + RenderingContext m_context; }; } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.idl b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.idl index 1ff0f64a46..28ad99a8c5 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.idl +++ b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.idl @@ -1,9 +1,12 @@ #import <HTML/CanvasRenderingContext2D.idl> #import <HTML/HTMLElement.idl> +#import <WebGL/WebGLRenderingContext.idl> + +typedef (CanvasRenderingContext2D or WebGLRenderingContext) RenderingContext; interface HTMLCanvasElement : HTMLElement { - CanvasRenderingContext2D? getContext(DOMString contextId); + RenderingContext? getContext(DOMString contextId, optional any options = null); attribute unsigned long width; attribute unsigned long height; diff --git a/Userland/Libraries/LibWeb/WebGL/Types.h b/Userland/Libraries/LibWeb/WebGL/Types.h new file mode 100644 index 0000000000..0d4df0e70f --- /dev/null +++ b/Userland/Libraries/LibWeb/WebGL/Types.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +// FIXME: This header is here just to satisfy the IDL code generator. diff --git a/Userland/Libraries/LibWeb/WebGL/Types.idl b/Userland/Libraries/LibWeb/WebGL/Types.idl new file mode 100644 index 0000000000..cd1522b87d --- /dev/null +++ b/Userland/Libraries/LibWeb/WebGL/Types.idl @@ -0,0 +1,15 @@ +typedef unsigned long GLenum; +typedef boolean GLboolean; +typedef unsigned long GLbitfield; +typedef long GLint; +typedef long GLsizei; + +// FIXME: These should be "unrestricted float" +typedef float GLfloat; +typedef float GLclampf; + +enum WebGLPowerPreference { + "default", + "low-power", + "high-performance" +}; diff --git a/Userland/Libraries/LibWeb/WebGL/WebGLContextAttributes.cpp b/Userland/Libraries/LibWeb/WebGL/WebGLContextAttributes.cpp new file mode 100644 index 0000000000..648c6c565e --- /dev/null +++ b/Userland/Libraries/LibWeb/WebGL/WebGLContextAttributes.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibJS/Runtime/Completion.h> +#include <LibJS/Runtime/GlobalObject.h> +#include <LibWeb/WebGL/WebGLContextAttributes.h> + +namespace Web::WebGL { + +JS::ThrowCompletionOr<WebGLContextAttributes> convert_value_to_context_attributes_dictionary(JS::GlobalObject& global_object, JS::Value value) +{ + auto& vm = global_object.vm(); + + // NOTE: This code was generated by the IDL code generator and then cleaned up. + if (!value.is_nullish() && !value.is_object()) + return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebGLContextAttributes"); + + WebGLContextAttributes context_attributes {}; + + JS::Value alpha; + if (value.is_nullish()) + alpha = JS::js_undefined(); + else + alpha = TRY(value.as_object().get("alpha")); + + bool alpha_value; + if (!alpha.is_undefined()) + alpha_value = alpha.to_boolean(); + else + alpha_value = true; + + context_attributes.alpha = alpha_value; + + JS::Value antialias; + if (value.is_nullish()) + antialias = JS::js_undefined(); + else + antialias = TRY(value.as_object().get("antialias")); + + bool antialias_value; + if (!antialias.is_undefined()) + antialias_value = antialias.to_boolean(); + else + antialias_value = true; + + context_attributes.antialias = antialias_value; + + JS::Value depth; + if (value.is_nullish()) + depth = JS::js_undefined(); + else + depth = TRY(value.as_object().get("depth")); + + bool depth_value; + if (!depth.is_undefined()) + depth_value = depth.to_boolean(); + else + depth_value = true; + + context_attributes.depth = depth_value; + + JS::Value desynchronized; + if (value.is_nullish()) + desynchronized = JS::js_undefined(); + else + desynchronized = TRY(value.as_object().get("desynchronized")); + + bool desynchronized_value; + + if (!desynchronized.is_undefined()) + desynchronized_value = desynchronized.to_boolean(); + else + desynchronized_value = false; + + context_attributes.desynchronized = desynchronized_value; + + JS::Value fail_if_major_performance_caveat; + if (value.is_nullish()) + fail_if_major_performance_caveat = JS::js_undefined(); + else + fail_if_major_performance_caveat = TRY(value.as_object().get("failIfMajorPerformanceCaveat")); + + bool fail_if_major_performance_caveat_value; + if (!fail_if_major_performance_caveat.is_undefined()) + fail_if_major_performance_caveat_value = fail_if_major_performance_caveat.to_boolean(); + else + fail_if_major_performance_caveat_value = false; + + context_attributes.fail_if_major_performance_caveat = fail_if_major_performance_caveat_value; + + JS::Value power_preference; + if (value.is_nullish()) + power_preference = JS::js_undefined(); + else + power_preference = TRY(value.as_object().get("powerPreference")); + + WebGLPowerPreference power_preference_value { WebGLPowerPreference::Default }; + + if (!power_preference.is_undefined()) { + auto power_preference_string = TRY(power_preference.to_string(global_object)); + + if (power_preference_string == "high-performance"sv) + power_preference_value = WebGLPowerPreference::HighPerformance; + else if (power_preference_string == "low-power"sv) + power_preference_value = WebGLPowerPreference::LowPower; + else if (power_preference_string == "default"sv) + power_preference_value = WebGLPowerPreference::Default; + else + return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::InvalidEnumerationValue, power_preference_string, "WebGLPowerPreference"); + } + + context_attributes.power_preference = power_preference_value; + + JS::Value premultiplied_alpha; + if (value.is_nullish()) + premultiplied_alpha = JS::js_undefined(); + else + premultiplied_alpha = TRY(value.as_object().get("premultipliedAlpha")); + + bool premultiplied_alpha_value; + + if (!premultiplied_alpha.is_undefined()) + premultiplied_alpha_value = premultiplied_alpha.to_boolean(); + else + premultiplied_alpha_value = true; + + context_attributes.premultiplied_alpha = premultiplied_alpha_value; + + JS::Value preserve_drawing_buffer; + if (value.is_nullish()) + preserve_drawing_buffer = JS::js_undefined(); + else + preserve_drawing_buffer = TRY(value.as_object().get("preserveDrawingBuffer")); + + bool preserve_drawing_buffer_value; + if (!preserve_drawing_buffer.is_undefined()) + preserve_drawing_buffer_value = preserve_drawing_buffer.to_boolean(); + else + preserve_drawing_buffer_value = false; + + context_attributes.preserve_drawing_buffer = preserve_drawing_buffer_value; + + JS::Value stencil; + if (value.is_nullish()) + stencil = JS::js_undefined(); + else + stencil = TRY(value.as_object().get("stencil")); + + bool stencil_value; + + if (!stencil.is_undefined()) + stencil_value = stencil.to_boolean(); + else + stencil_value = false; + + context_attributes.stencil = stencil_value; + + return context_attributes; +} + +} diff --git a/Userland/Libraries/LibWeb/WebGL/WebGLContextAttributes.h b/Userland/Libraries/LibWeb/WebGL/WebGLContextAttributes.h new file mode 100644 index 0000000000..8888d0771b --- /dev/null +++ b/Userland/Libraries/LibWeb/WebGL/WebGLContextAttributes.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibJS/Forward.h> + +namespace Web::WebGL { + +enum class WebGLPowerPreference { + Default, + LowPower, + HighPerformance, +}; + +// https://www.khronos.org/registry/webgl/specs/latest/1.0/#WEBGLCONTEXTATTRIBUTES +struct WebGLContextAttributes { + bool alpha { true }; + bool depth { true }; + bool stencil { false }; + bool antialias { true }; + bool premultiplied_alpha { true }; + bool preserve_drawing_buffer { false }; + WebGLPowerPreference power_preference { WebGLPowerPreference::Default }; + bool fail_if_major_performance_caveat { false }; + bool desynchronized { false }; +}; + +JS::ThrowCompletionOr<WebGLContextAttributes> convert_value_to_context_attributes_dictionary(JS::GlobalObject& global_object, JS::Value value); + +} diff --git a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp new file mode 100644 index 0000000000..332edc1969 --- /dev/null +++ b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibWeb/Bindings/Wrapper.h> +#include <LibWeb/HTML/HTMLCanvasElement.h> +#include <LibWeb/WebGL/WebGLContextEvent.h> +#include <LibWeb/WebGL/WebGLRenderingContext.h> + +namespace Web::WebGL { + +// https://www.khronos.org/registry/webgl/specs/latest/1.0/#fire-a-webgl-context-event +static void fire_webgl_context_event(HTML::HTMLCanvasElement& canvas_element, FlyString const& type) +{ + // To fire a WebGL context event named e means that an event using the WebGLContextEvent interface, with its type attribute [DOM4] initialized to e, its cancelable attribute initialized to true, and its isTrusted attribute [DOM4] initialized to true, is to be dispatched at the given object. + // FIXME: Consider setting a status message. + auto event = WebGLContextEvent::create(type, WebGLContextEventInit {}); + event->set_is_trusted(true); + event->set_cancelable(true); + canvas_element.dispatch_event(move(event)); +} + +// https://www.khronos.org/registry/webgl/specs/latest/1.0/#fire-a-webgl-context-creation-error +static void fire_webgl_context_creation_error(HTML::HTMLCanvasElement& canvas_element) +{ + // 1. Fire a WebGL context event named "webglcontextcreationerror" at canvas, optionally with its statusMessage attribute set to a platform dependent string about the nature of the failure. + fire_webgl_context_event(canvas_element, "webglcontextcreationerror"sv); +} + +JS::ThrowCompletionOr<RefPtr<WebGLRenderingContext>> WebGLRenderingContext::create(HTML::HTMLCanvasElement& canvas_element, JS::Value options) +{ + // We should be coming here from getContext being called on a wrapped <canvas> element. + VERIFY(canvas_element.wrapper()); + auto context_attributes = TRY(convert_value_to_context_attributes_dictionary(canvas_element.wrapper()->global_object(), options)); + + bool created_bitmap = canvas_element.create_bitmap(/* minimum_width= */ 1, /* minimum_height= */ 1); + if (!created_bitmap) { + fire_webgl_context_creation_error(canvas_element); + return RefPtr<WebGLRenderingContext> { nullptr }; + } + + // FIXME: LibGL currently doesn't propagate context creation errors. + auto context = GL::create_context(*canvas_element.bitmap()); + + return adopt_ref(*new WebGLRenderingContext(canvas_element, move(context), context_attributes, context_attributes)); +} + +} diff --git a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContext.h b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContext.h new file mode 100644 index 0000000000..7798009798 --- /dev/null +++ b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContext.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibWeb/Bindings/Wrappable.h> +#include <LibWeb/WebGL/WebGLRenderingContextBase.h> + +namespace Web::WebGL { + +class WebGLRenderingContext + : public WebGLRenderingContextBase + , public Bindings::Wrappable { +public: + using WrapperType = Bindings::WebGLRenderingContextWrapper; + + static JS::ThrowCompletionOr<RefPtr<WebGLRenderingContext>> create(HTML::HTMLCanvasElement& canvas_element, JS::Value options); + + virtual ~WebGLRenderingContext() override = default; + +private: + WebGLRenderingContext(HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters) + : WebGLRenderingContextBase(canvas_element, move(context), move(context_creation_parameters), move(actual_context_parameters)) + { + } +}; + +} diff --git a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContext.idl b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContext.idl new file mode 100644 index 0000000000..f87b8d1023 --- /dev/null +++ b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContext.idl @@ -0,0 +1,7 @@ +#import <WebGL/WebGLRenderingContextBase.idl> + +[Exposed=(Window,Worker)] +interface WebGLRenderingContext { +}; + +WebGLRenderingContext includes WebGLRenderingContextBase; diff --git a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp new file mode 100644 index 0000000000..774cc6adcb --- /dev/null +++ b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibGL/GLContext.h> +#include <LibWeb/HTML/HTMLCanvasElement.h> +#include <LibWeb/WebGL/WebGLRenderingContextBase.h> + +namespace Web::WebGL { + +WebGLRenderingContextBase::WebGLRenderingContextBase(HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters) + : m_canvas_element(canvas_element) + , m_context(move(context)) + , m_context_creation_parameters(move(context_creation_parameters)) + , m_actual_context_parameters(move(actual_context_parameters)) +{ +} + +WebGLRenderingContextBase::~WebGLRenderingContextBase() = default; + +} diff --git a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.h b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.h new file mode 100644 index 0000000000..70ba19978e --- /dev/null +++ b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/RefCounted.h> +#include <AK/WeakPtr.h> +#include <AK/Weakable.h> +#include <LibGL/GLContext.h> +#include <LibWeb/Forward.h> +#include <LibWeb/WebGL/WebGLContextAttributes.h> + +namespace Web::WebGL { + +class WebGLRenderingContextBase + : public RefCounted<WebGLRenderingContextBase> + , public Weakable<WebGLRenderingContextBase> { +public: + virtual ~WebGLRenderingContextBase(); + +protected: + WebGLRenderingContextBase(HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters); + +private: + WeakPtr<HTML::HTMLCanvasElement> m_canvas_element; + + NonnullOwnPtr<GL::GLContext> m_context; + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#context-creation-parameters + // Each WebGLRenderingContext has context creation parameters, set upon creation, in a WebGLContextAttributes object. + WebGLContextAttributes m_context_creation_parameters {}; + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#actual-context-parameters + // Each WebGLRenderingContext has actual context parameters, set each time the drawing buffer is created, in a WebGLContextAttributes object. + WebGLContextAttributes m_actual_context_parameters {}; + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#webgl-context-lost-flag + // Each WebGLRenderingContext has a webgl context lost flag, which is initially unset. + bool m_context_lost { false }; + + // WebGL presents its drawing buffer to the HTML page compositor immediately before a compositing operation, but only if at least one of the following has occurred since the previous compositing operation: + // - Context creation + // - Canvas resize + // - clear, drawArrays, or drawElements has been called while the drawing buffer is the currently bound framebuffer + bool m_should_present { true }; +}; + +} diff --git a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.idl b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.idl new file mode 100644 index 0000000000..b88f38acdb --- /dev/null +++ b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.idl @@ -0,0 +1,397 @@ +#import <WebGL/Types.idl> + +dictionary WebGLContextAttributes { + boolean alpha = true; + boolean depth = true; + boolean stencil = false; + boolean antialias = true; + boolean premultipliedAlpha = true; + boolean preserveDrawingBuffer = false; + WebGLPowerPreference powerPreference = "default"; + boolean failIfMajorPerformanceCaveat = false; + boolean desynchronized = false; +}; + +interface mixin WebGLRenderingContextBase { + // Enums + // ClearBufferMask + const GLenum DEPTH_BUFFER_BIT = 0x00000100; + const GLenum STENCIL_BUFFER_BIT = 0x00000400; + const GLenum COLOR_BUFFER_BIT = 0x00004000; + + // BeginMode + const GLenum POINTS = 0x0000; + const GLenum LINES = 0x0001; + const GLenum LINE_LOOP = 0x0002; + const GLenum LINE_STRIP = 0x0003; + const GLenum TRIANGLES = 0x0004; + const GLenum TRIANGLE_STRIP = 0x0005; + const GLenum TRIANGLE_FAN = 0x0006; + + // BlendingFactorDest + const GLenum ZERO = 0; + const GLenum ONE = 1; + const GLenum SRC_COLOR = 0x0300; + const GLenum ONE_MINUS_SRC_COLOR = 0x0301; + const GLenum SRC_ALPHA = 0x0302; + const GLenum ONE_MINUS_SRC_ALPHA = 0x0303; + const GLenum DST_ALPHA = 0x0304; + const GLenum ONE_MINUS_DST_ALPHA = 0x0305; + + // BlendingFactorSrc + const GLenum DST_COLOR = 0x0306; + const GLenum ONE_MINUS_DST_COLOR = 0x0307; + const GLenum SRC_ALPHA_SATURATE = 0x0308; + + // BlendEquationSeparate + const GLenum FUNC_ADD = 0x8006; + const GLenum BLEND_EQUATION = 0x8009; + const GLenum BLEND_EQUATION_RGB = 0x8009; // NOTE: Intentionally the same as BLEND_EQUATION + const GLenum BLEND_EQUATION_ALPHA = 0x883D; + + // BlendSubtract + const GLenum FUNC_SUBTRACT = 0x800A; + const GLenum FUNC_REVERSE_SUBTRACT = 0x800B; + + // Separate Blend Functions + const GLenum BLEND_DST_RGB = 0x80C8; + const GLenum BLEND_SRC_RGB = 0x80C9; + const GLenum BLEND_DST_ALPHA = 0x80CA; + const GLenum BLEND_SRC_ALPHA = 0x80CB; + const GLenum CONSTANT_COLOR = 0x8001; + const GLenum ONE_MINUS_CONSTANT_COLOR = 0x8002; + const GLenum CONSTANT_ALPHA = 0x8003; + const GLenum ONE_MINUS_CONSTANT_ALPHA = 0x8004; + const GLenum BLEND_COLOR = 0x8005; + + // Buffer Objects + const GLenum ARRAY_BUFFER = 0x8892; + const GLenum ELEMENT_ARRAY_BUFFER = 0x8893; + const GLenum ARRAY_BUFFER_BINDING = 0x8894; + const GLenum ELEMENT_ARRAY_BUFFER_BINDING = 0x8895; + + const GLenum STREAM_DRAW = 0x88E0; + const GLenum STATIC_DRAW = 0x88E4; + const GLenum DYNAMIC_DRAW = 0x88E8; + + const GLenum BUFFER_SIZE = 0x8764; + const GLenum BUFFER_USAGE = 0x8765; + + const GLenum CURRENT_VERTEX_ATTRIB = 0x8626; + + // CullFaceMode + const GLenum FRONT = 0x0404; + const GLenum BACK = 0x0405; + const GLenum FRONT_AND_BACK = 0x0408; + + // EnableCap + // TEXTURE_2D + const GLenum CULL_FACE = 0x0B44; + const GLenum BLEND = 0x0BE2; + const GLenum DITHER = 0x0BD0; + const GLenum STENCIL_TEST = 0x0B90; + const GLenum DEPTH_TEST = 0x0B71; + const GLenum SCISSOR_TEST = 0x0C11; + const GLenum POLYGON_OFFSET_FILL = 0x8037; + const GLenum SAMPLE_ALPHA_TO_COVERAGE = 0x809E; + const GLenum SAMPLE_COVERAGE = 0x80A0; + + // ErrorCode + const GLenum NO_ERROR = 0; + const GLenum INVALID_ENUM = 0x0500; + const GLenum INVALID_VALUE = 0x0501; + const GLenum INVALID_OPERATION = 0x0502; + const GLenum OUT_OF_MEMORY = 0x0505; + + // FrontFaceDirection + const GLenum CW = 0x0900; + const GLenum CCW = 0x0901; + + // GetPName + const GLenum LINE_WIDTH = 0x0B21; + const GLenum ALIASED_POINT_SIZE_RANGE = 0x846D; + const GLenum ALIASED_LINE_WIDTH_RANGE = 0x846E; + const GLenum CULL_FACE_MODE = 0x0B45; + const GLenum FRONT_FACE = 0x0B46; + const GLenum DEPTH_RANGE = 0x0B70; + const GLenum DEPTH_WRITEMASK = 0x0B72; + const GLenum DEPTH_CLEAR_VALUE = 0x0B73; + const GLenum DEPTH_FUNC = 0x0B74; + const GLenum STENCIL_CLEAR_VALUE = 0x0B91; + const GLenum STENCIL_FUNC = 0x0B92; + const GLenum STENCIL_FAIL = 0x0B94; + const GLenum STENCIL_PASS_DEPTH_FAIL = 0x0B95; + const GLenum STENCIL_PASS_DEPTH_PASS = 0x0B96; + const GLenum STENCIL_REF = 0x0B97; + const GLenum STENCIL_VALUE_MASK = 0x0B93; + const GLenum STENCIL_WRITEMASK = 0x0B98; + const GLenum STENCIL_BACK_FUNC = 0x8800; + const GLenum STENCIL_BACK_FAIL = 0x8801; + const GLenum STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802; + const GLenum STENCIL_BACK_PASS_DEPTH_PASS = 0x8803; + const GLenum STENCIL_BACK_REF = 0x8CA3; + const GLenum STENCIL_BACK_VALUE_MASK = 0x8CA4; + const GLenum STENCIL_BACK_WRITEMASK = 0x8CA5; + const GLenum VIEWPORT = 0x0BA2; + const GLenum SCISSOR_BOX = 0x0C10; + const GLenum COLOR_CLEAR_VALUE = 0x0C22; + const GLenum COLOR_WRITEMASK = 0x0C23; + const GLenum UNPACK_ALIGNMENT = 0x0CF5; + const GLenum PACK_ALIGNMENT = 0x0D05; + const GLenum MAX_TEXTURE_SIZE = 0x0D33; + const GLenum MAX_VIEWPORT_DIMS = 0x0D3A; + const GLenum SUBPIXEL_BITS = 0x0D50; + const GLenum RED_BITS = 0x0D52; + const GLenum GREEN_BITS = 0x0D53; + const GLenum BLUE_BITS = 0x0D54; + const GLenum ALPHA_BITS = 0x0D55; + const GLenum DEPTH_BITS = 0x0D56; + const GLenum STENCIL_BITS = 0x0D57; + const GLenum POLYGON_OFFSET_UNITS = 0x2A00; + const GLenum POLYGON_OFFSET_FACTOR = 0x8038; + const GLenum TEXTURE_BINDING_2D = 0x8069; + const GLenum SAMPLE_BUFFERS = 0x80A8; + const GLenum SAMPLES = 0x80A9; + const GLenum SAMPLE_COVERAGE_VALUE = 0x80AA; + const GLenum SAMPLE_COVERAGE_INVERT = 0x80AB; + + // GetTexureParameter + const GLenum COMPRESSED_TEXTURE_FORMATS = 0x86A3; + + // HintMode + const GLenum DONT_CARE = 0x1100; + const GLenum FASTEST = 0x1101; + const GLenum NICEST = 0x1102; + + // HintTarget + const GLenum GENERATE_MIPMAP_HINT = 0x8192; + + // DataType + const GLenum BYTE = 0x1400; + const GLenum UNSIGNED_BYTE = 0x1401; + const GLenum SHORT = 0x1402; + const GLenum UNSIGNED_SHORT = 0x1403; + const GLenum INT = 0x1404; + const GLenum UNSIGNED_INT = 0x1405; + const GLenum FLOAT = 0x1406; + + // PixelFormat + const GLenum DEPTH_COMPONENT = 0x1902; + const GLenum ALPHA = 0x1906; + const GLenum RGB = 0x1907; + const GLenum RGBA = 0x1908; + const GLenum LUMINANCE = 0x1909; + const GLenum LUMINANCE_ALPHA = 0x190A; + + // PixelType + const GLenum UNSIGNED_SHORT_4_4_4_4 = 0x8033; + const GLenum UNSIGNED_SHORT_5_5_5_1 = 0x8034; + const GLenum UNSIGNED_SHORT_5_6_5 = 0x8363; + + // Shaders + const GLenum FRAGMENT_SHADER = 0x8B30; + const GLenum VERTEX_SHADER = 0x8B31; + const GLenum MAX_VERTEX_ATTRIBS = 0x8869; + const GLenum MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB; + const GLenum MAX_VARYING_VECTORS = 0x8DFC; + const GLenum MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D; + const GLenum MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C; + const GLenum MAX_TEXTURE_IMAGE_UNITS = 0x8872; + const GLenum MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD; + const GLenum SHADER_TYPE = 0x8B4F; + const GLenum DELETE_STATUS = 0x8B80; + const GLenum LINK_STATUS = 0x8B82; + const GLenum VALIDATE_STATUS = 0x8B83; + const GLenum ATTACHED_SHADERS = 0x8B85; + const GLenum ACTIVE_UNIFORMS = 0x8B86; + const GLenum ACTIVE_ATTRIBUTES = 0x8B89; + const GLenum SHADING_LANGUAGE_VERSION = 0x8B8C; + const GLenum CURRENT_PROGRAM = 0x8B8D; + + // StencilFunction + const GLenum NEVER = 0x0200; + const GLenum LESS = 0x0201; + const GLenum EQUAL = 0x0202; + const GLenum LEQUAL = 0x0203; + const GLenum GREATER = 0x0204; + const GLenum NOTEQUAL = 0x0205; + const GLenum GEQUAL = 0x0206; + const GLenum ALWAYS = 0x0207; + + // StencilOp + const GLenum KEEP = 0x1E00; + const GLenum REPLACE = 0x1E01; + const GLenum INCR = 0x1E02; + const GLenum DECR = 0x1E03; + const GLenum INVERT = 0x150A; + const GLenum INCR_WRAP = 0x8507; + const GLenum DECR_WRAP = 0x8508; + + // StringName + const GLenum VENDOR = 0x1F00; + const GLenum RENDERER = 0x1F01; + const GLenum VERSION = 0x1F02; + + // TextureMagFilter + const GLenum NEAREST = 0x2600; + const GLenum LINEAR = 0x2601; + + // TextureMinFilter + const GLenum NEAREST_MIPMAP_NEAREST = 0x2700; + const GLenum LINEAR_MIPMAP_NEAREST = 0x2701; + const GLenum NEAREST_MIPMAP_LINEAR = 0x2702; + const GLenum LINEAR_MIPMAP_LINEAR = 0x2703; + + // TextureParameterName + const GLenum TEXTURE_MAG_FILTER = 0x2800; + const GLenum TEXTURE_MIN_FILTER = 0x2801; + const GLenum TEXTURE_WRAP_S = 0x2802; + const GLenum TEXTURE_WRAP_T = 0x2803; + + // TextureTarget + const GLenum TEXTURE_2D = 0x0DE1; + const GLenum TEXTURE = 0x1702; + + const GLenum TEXTURE_CUBE_MAP = 0x8513; + const GLenum TEXTURE_BINDING_CUBE_MAP = 0x8514; + const GLenum TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; + const GLenum TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516; + const GLenum TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517; + const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518; + const GLenum TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519; + const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A; + const GLenum MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C; + + // TextureUnit + const GLenum TEXTURE0 = 0x84C0; + const GLenum TEXTURE1 = 0x84C1; + const GLenum TEXTURE2 = 0x84C2; + const GLenum TEXTURE3 = 0x84C3; + const GLenum TEXTURE4 = 0x84C4; + const GLenum TEXTURE5 = 0x84C5; + const GLenum TEXTURE6 = 0x84C6; + const GLenum TEXTURE7 = 0x84C7; + const GLenum TEXTURE8 = 0x84C8; + const GLenum TEXTURE9 = 0x84C9; + const GLenum TEXTURE10 = 0x84CA; + const GLenum TEXTURE11 = 0x84CB; + const GLenum TEXTURE12 = 0x84CC; + const GLenum TEXTURE13 = 0x84CD; + const GLenum TEXTURE14 = 0x84CE; + const GLenum TEXTURE15 = 0x84CF; + const GLenum TEXTURE16 = 0x84D0; + const GLenum TEXTURE17 = 0x84D1; + const GLenum TEXTURE18 = 0x84D2; + const GLenum TEXTURE19 = 0x84D3; + const GLenum TEXTURE20 = 0x84D4; + const GLenum TEXTURE21 = 0x84D5; + const GLenum TEXTURE22 = 0x84D6; + const GLenum TEXTURE23 = 0x84D7; + const GLenum TEXTURE24 = 0x84D8; + const GLenum TEXTURE25 = 0x84D9; + const GLenum TEXTURE26 = 0x84DA; + const GLenum TEXTURE27 = 0x84DB; + const GLenum TEXTURE28 = 0x84DC; + const GLenum TEXTURE29 = 0x84DD; + const GLenum TEXTURE30 = 0x84DE; + const GLenum TEXTURE31 = 0x84DF; + const GLenum ACTIVE_TEXTURE = 0x84E0; + + // TextureWrapMode + const GLenum REPEAT = 0x2901; + const GLenum CLAMP_TO_EDGE = 0x812F; + const GLenum MIRRORED_REPEAT = 0x8370; + + // Uniform Types + const GLenum FLOAT_VEC2 = 0x8B50; + const GLenum FLOAT_VEC3 = 0x8B51; + const GLenum FLOAT_VEC4 = 0x8B52; + const GLenum INT_VEC2 = 0x8B53; + const GLenum INT_VEC3 = 0x8B54; + const GLenum INT_VEC4 = 0x8B55; + const GLenum BOOL = 0x8B56; + const GLenum BOOL_VEC2 = 0x8B57; + const GLenum BOOL_VEC3 = 0x8B58; + const GLenum BOOL_VEC4 = 0x8B59; + const GLenum FLOAT_MAT2 = 0x8B5A; + const GLenum FLOAT_MAT3 = 0x8B5B; + const GLenum FLOAT_MAT4 = 0x8B5C; + const GLenum SAMPLER_2D = 0x8B5E; + const GLenum SAMPLER_CUBE = 0x8B60; + + // Vertex Arrays + const GLenum VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622; + const GLenum VERTEX_ATTRIB_ARRAY_SIZE = 0x8623; + const GLenum VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624; + const GLenum VERTEX_ATTRIB_ARRAY_TYPE = 0x8625; + const GLenum VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A; + const GLenum VERTEX_ATTRIB_ARRAY_POINTER = 0x8645; + const GLenum VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F; + + // Read Format + const GLenum IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A; + const GLenum IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B; + + // Shader Source + const GLenum COMPILE_STATUS = 0x8B81; + + // Shader Precision-Specified Types + const GLenum LOW_FLOAT = 0x8DF0; + const GLenum MEDIUM_FLOAT = 0x8DF1; + const GLenum HIGH_FLOAT = 0x8DF2; + const GLenum LOW_INT = 0x8DF3; + const GLenum MEDIUM_INT = 0x8DF4; + const GLenum HIGH_INT = 0x8DF5; + + // Framebuffer Object + const GLenum FRAMEBUFFER = 0x8D40; + const GLenum RENDERBUFFER = 0x8D41; + + const GLenum RGBA4 = 0x8056; + const GLenum RGB5_A1 = 0x8057; + const GLenum RGB565 = 0x8D62; + const GLenum DEPTH_COMPONENT16 = 0x81A5; + const GLenum STENCIL_INDEX8 = 0x8D48; + const GLenum DEPTH_STENCIL = 0x84F9; + + const GLenum RENDERBUFFER_WIDTH = 0x8D42; + const GLenum RENDERBUFFER_HEIGHT = 0x8D43; + const GLenum RENDERBUFFER_INTERNAL_FORMAT = 0x8D44; + const GLenum RENDERBUFFER_RED_SIZE = 0x8D50; + const GLenum RENDERBUFFER_GREEN_SIZE = 0x8D51; + const GLenum RENDERBUFFER_BLUE_SIZE = 0x8D52; + const GLenum RENDERBUFFER_ALPHA_SIZE = 0x8D53; + const GLenum RENDERBUFFER_DEPTH_SIZE = 0x8D54; + const GLenum RENDERBUFFER_STENCIL_SIZE = 0x8D55; + + const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0; + const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1; + const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2; + const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3; + + const GLenum COLOR_ATTACHMENT0 = 0x8CE0; + const GLenum DEPTH_ATTACHMENT = 0x8D00; + const GLenum STENCIL_ATTACHMENT = 0x8D20; + const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A; + + const GLenum NONE = 0; + + const GLenum FRAMEBUFFER_COMPLETE = 0x8CD5; + const GLenum FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6; + const GLenum FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7; + const GLenum FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9; + const GLenum FRAMEBUFFER_UNSUPPORTED = 0x8CDD; + + const GLenum FRAMEBUFFER_BINDING = 0x8CA6; + const GLenum RENDERBUFFER_BINDING = 0x8CA7; + const GLenum MAX_RENDERBUFFER_SIZE = 0x84E8; + + const GLenum INVALID_FRAMEBUFFER_OPERATION = 0x0506; + + // WebGL-specific enums + const GLenum UNPACK_FLIP_Y_WEBGL = 0x9240; + const GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241; + const GLenum CONTEXT_LOST_WEBGL = 0x9242; + const GLenum UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243; + const GLenum BROWSER_DEFAULT_WEBGL = 0x9244; +}; diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 2bb2bcc731..b379a86e95 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -173,6 +173,7 @@ libweb_js_wrapper(UIEvents/UIEvent) libweb_js_wrapper(URL/URL) libweb_js_wrapper(URL/URLSearchParams ITERABLE) libweb_js_wrapper(WebGL/WebGLContextEvent) +libweb_js_wrapper(WebGL/WebGLRenderingContext) libweb_js_wrapper(WebSockets/WebSocket) libweb_js_wrapper(XHR/ProgressEvent) libweb_js_wrapper(XHR/XMLHttpRequest) |