/src/serenity/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <LibWeb/Bindings/Intrinsics.h> |
8 | | #include <LibWeb/Bindings/WebGLRenderingContextPrototype.h> |
9 | | #include <LibWeb/DOM/Document.h> |
10 | | #include <LibWeb/HTML/HTMLCanvasElement.h> |
11 | | #include <LibWeb/WebGL/EventNames.h> |
12 | | #include <LibWeb/WebGL/WebGLContextEvent.h> |
13 | | #include <LibWeb/WebGL/WebGLRenderingContext.h> |
14 | | |
15 | | namespace Web::WebGL { |
16 | | |
17 | | JS_DEFINE_ALLOCATOR(WebGLRenderingContext); |
18 | | |
19 | | // https://www.khronos.org/registry/webgl/specs/latest/1.0/#fire-a-webgl-context-event |
20 | | static void fire_webgl_context_event(HTML::HTMLCanvasElement& canvas_element, FlyString const& type) |
21 | 0 | { |
22 | | // 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. |
23 | | // FIXME: Consider setting a status message. |
24 | 0 | auto event = WebGLContextEvent::create(canvas_element.realm(), type, WebGLContextEventInit {}); |
25 | 0 | event->set_is_trusted(true); |
26 | 0 | event->set_cancelable(true); |
27 | 0 | canvas_element.dispatch_event(*event); |
28 | 0 | } |
29 | | |
30 | | // https://www.khronos.org/registry/webgl/specs/latest/1.0/#fire-a-webgl-context-creation-error |
31 | | static void fire_webgl_context_creation_error(HTML::HTMLCanvasElement& canvas_element) |
32 | 0 | { |
33 | | // 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. |
34 | 0 | fire_webgl_context_event(canvas_element, EventNames::webglcontextcreationerror); |
35 | 0 | } |
36 | | |
37 | | JS::ThrowCompletionOr<JS::GCPtr<WebGLRenderingContext>> WebGLRenderingContext::create(JS::Realm& realm, HTML::HTMLCanvasElement& canvas_element, JS::Value options) |
38 | 0 | { |
39 | | // We should be coming here from getContext being called on a wrapped <canvas> element. |
40 | 0 | auto context_attributes = TRY(convert_value_to_context_attributes_dictionary(canvas_element.vm(), options)); |
41 | | |
42 | 0 | bool created_bitmap = canvas_element.create_bitmap(/* minimum_width= */ 1, /* minimum_height= */ 1); |
43 | 0 | if (!created_bitmap) { |
44 | 0 | fire_webgl_context_creation_error(canvas_element); |
45 | 0 | return JS::GCPtr<WebGLRenderingContext> { nullptr }; |
46 | 0 | } |
47 | | |
48 | 0 | VERIFY(canvas_element.bitmap()); |
49 | 0 | auto context = OpenGLContext::create(*canvas_element.bitmap()); |
50 | |
|
51 | 0 | if (!context) { |
52 | 0 | fire_webgl_context_creation_error(canvas_element); |
53 | 0 | return JS::GCPtr<WebGLRenderingContext> { nullptr }; |
54 | 0 | } |
55 | | |
56 | 0 | return realm.heap().allocate<WebGLRenderingContext>(realm, realm, canvas_element, context.release_nonnull(), context_attributes, context_attributes); |
57 | 0 | } |
58 | | |
59 | | WebGLRenderingContext::WebGLRenderingContext(JS::Realm& realm, HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<OpenGLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters) |
60 | 0 | : WebGLRenderingContextBase(realm, canvas_element, move(context), move(context_creation_parameters), move(actual_context_parameters)) |
61 | 0 | { |
62 | 0 | } |
63 | | |
64 | 0 | WebGLRenderingContext::~WebGLRenderingContext() = default; |
65 | | |
66 | | void WebGLRenderingContext::initialize(JS::Realm& realm) |
67 | 0 | { |
68 | 0 | Base::initialize(realm); |
69 | 0 | WEB_SET_PROTOTYPE_FOR_INTERFACE(WebGLRenderingContext); |
70 | 0 | } |
71 | | |
72 | | } |