WebGLRenderingContext.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. /*
  2. * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibWeb/Bindings/Wrapper.h>
  7. #include <LibWeb/HTML/HTMLCanvasElement.h>
  8. #include <LibWeb/WebGL/WebGLContextEvent.h>
  9. #include <LibWeb/WebGL/WebGLRenderingContext.h>
  10. namespace Web::WebGL {
  11. // https://www.khronos.org/registry/webgl/specs/latest/1.0/#fire-a-webgl-context-event
  12. static void fire_webgl_context_event(HTML::HTMLCanvasElement& canvas_element, FlyString const& type)
  13. {
  14. // 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.
  15. // FIXME: Consider setting a status message.
  16. auto event = WebGLContextEvent::create(type, WebGLContextEventInit {});
  17. event->set_is_trusted(true);
  18. event->set_cancelable(true);
  19. canvas_element.dispatch_event(move(event));
  20. }
  21. // https://www.khronos.org/registry/webgl/specs/latest/1.0/#fire-a-webgl-context-creation-error
  22. static void fire_webgl_context_creation_error(HTML::HTMLCanvasElement& canvas_element)
  23. {
  24. // 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.
  25. fire_webgl_context_event(canvas_element, "webglcontextcreationerror"sv);
  26. }
  27. JS::ThrowCompletionOr<RefPtr<WebGLRenderingContext>> WebGLRenderingContext::create(HTML::HTMLCanvasElement& canvas_element, JS::Value options)
  28. {
  29. // We should be coming here from getContext being called on a wrapped <canvas> element.
  30. VERIFY(canvas_element.wrapper());
  31. auto context_attributes = TRY(convert_value_to_context_attributes_dictionary(canvas_element.wrapper()->global_object(), options));
  32. bool created_bitmap = canvas_element.create_bitmap(/* minimum_width= */ 1, /* minimum_height= */ 1);
  33. if (!created_bitmap) {
  34. fire_webgl_context_creation_error(canvas_element);
  35. return RefPtr<WebGLRenderingContext> { nullptr };
  36. }
  37. #ifndef __serenity__
  38. // FIXME: Make WebGL work on other platforms.
  39. (void)context_attributes;
  40. dbgln("FIXME: WebGL not supported on the current platform");
  41. fire_webgl_context_creation_error(canvas_element);
  42. return RefPtr<WebGLRenderingContext> { nullptr };
  43. #else
  44. // FIXME: LibGL currently doesn't propagate context creation errors.
  45. auto context = GL::create_context(*canvas_element.bitmap());
  46. return adopt_ref(*new WebGLRenderingContext(canvas_element, move(context), context_attributes, context_attributes));
  47. #endif
  48. }
  49. }