Coverage Report

Created: 2025-08-28 06:26

/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
}