2022-06-04 04:22:42 +01:00
/*
* Copyright ( c ) 2022 , Luke Wilde < lukew @ serenityos . org >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
2022-09-25 18:12:50 -06:00
# include <LibWeb/Bindings/Intrinsics.h>
2022-08-08 22:29:40 +02:00
# include <LibWeb/DOM/Document.h>
2022-06-04 04:22:42 +01:00
# include <LibWeb/HTML/HTMLCanvasElement.h>
2023-04-09 12:57:23 +02:00
# include <LibWeb/WebGL/EventNames.h>
2022-06-04 04:22:42 +01:00
# include <LibWeb/WebGL/WebGLContextEvent.h>
# include <LibWeb/WebGL/WebGLRenderingContext.h>
namespace Web : : WebGL {
2023-11-19 19:47:52 +01:00
JS_DEFINE_ALLOCATOR ( WebGLRenderingContext ) ;
2022-06-04 04:22:42 +01:00
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#fire-a-webgl-context-event
2023-04-09 12:57:23 +02:00
static void fire_webgl_context_event ( HTML : : HTMLCanvasElement & canvas_element , FlyString const & type )
2022-06-04 04:22:42 +01:00
{
// 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.
2023-08-13 13:05:26 +02:00
auto event = WebGLContextEvent : : create ( canvas_element . realm ( ) , type , WebGLContextEventInit { } ) ;
2022-06-04 04:22:42 +01:00
event - > set_is_trusted ( true ) ;
event - > set_cancelable ( true ) ;
2022-08-08 22:29:40 +02:00
canvas_element . dispatch_event ( * event ) ;
2022-06-04 04:22:42 +01:00
}
// 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.
2023-04-09 12:57:23 +02:00
fire_webgl_context_event ( canvas_element , EventNames : : webglcontextcreationerror ) ;
2022-06-04 04:22:42 +01:00
}
2022-09-25 18:12:50 -06:00
JS : : ThrowCompletionOr < JS : : GCPtr < WebGLRenderingContext > > WebGLRenderingContext : : create ( JS : : Realm & realm , HTML : : HTMLCanvasElement & canvas_element , JS : : Value options )
2022-06-04 04:22:42 +01:00
{
// We should be coming here from getContext being called on a wrapped <canvas> element.
2022-08-28 13:42:07 +02:00
auto context_attributes = TRY ( convert_value_to_context_attributes_dictionary ( canvas_element . vm ( ) , options ) ) ;
2022-06-04 04:22:42 +01:00
bool created_bitmap = canvas_element . create_bitmap ( /* minimum_width= */ 1 , /* minimum_height= */ 1 ) ;
if ( ! created_bitmap ) {
fire_webgl_context_creation_error ( canvas_element ) ;
2022-09-02 15:53:02 +02:00
return JS : : GCPtr < WebGLRenderingContext > { nullptr } ;
2022-06-04 04:22:42 +01:00
}
2022-09-16 05:58:30 -06:00
auto context_or_error = GL : : create_context ( * canvas_element . bitmap ( ) ) ;
if ( context_or_error . is_error ( ) ) {
fire_webgl_context_creation_error ( canvas_element ) ;
return JS : : GCPtr < WebGLRenderingContext > { nullptr } ;
}
2023-08-13 13:05:26 +02:00
return realm . heap ( ) . allocate < WebGLRenderingContext > ( realm , realm , canvas_element , context_or_error . release_value ( ) , context_attributes , context_attributes ) ;
2022-06-04 04:22:42 +01:00
}
2022-09-25 18:12:50 -06:00
WebGLRenderingContext : : WebGLRenderingContext ( JS : : Realm & realm , HTML : : HTMLCanvasElement & canvas_element , NonnullOwnPtr < GL : : GLContext > context , WebGLContextAttributes context_creation_parameters , WebGLContextAttributes actual_context_parameters )
: WebGLRenderingContextBase ( realm , canvas_element , move ( context ) , move ( context_creation_parameters ) , move ( actual_context_parameters ) )
2022-09-02 15:53:02 +02:00
{
}
WebGLRenderingContext : : ~ WebGLRenderingContext ( ) = default ;
2023-08-07 08:41:28 +02:00
void WebGLRenderingContext : : initialize ( JS : : Realm & realm )
2023-01-10 06:28:20 -05:00
{
2023-08-07 08:41:28 +02:00
Base : : initialize ( realm ) ;
2023-11-22 12:55:21 +13:00
set_prototype ( & Bindings : : ensure_web_prototype < Bindings : : WebGLRenderingContextPrototype > ( realm , " WebGLRenderingContext " _fly_string ) ) ;
2023-01-10 06:28:20 -05:00
}
2022-06-04 04:22:42 +01:00
}