From a6617e1096ba5fffbb1884f122a8c03155167b62 Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Mon, 13 Jun 2022 16:54:27 +0100 Subject: [PATCH] LibWeb/WebGL: Implement error handling and getError() --- .../WebGL/WebGLRenderingContextBase.cpp | 32 +++++++++++++++++++ .../LibWeb/WebGL/WebGLRenderingContextBase.h | 5 +++ .../WebGL/WebGLRenderingContextBase.idl | 2 ++ 3 files changed, 39 insertions(+) diff --git a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp index 35144898f1..d05435182a 100644 --- a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp +++ b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp @@ -21,6 +21,13 @@ WebGLRenderingContextBase::WebGLRenderingContextBase(HTML::HTMLCanvasElement& ca WebGLRenderingContextBase::~WebGLRenderingContextBase() = default; +#define RETURN_WITH_WEBGL_ERROR_IF(condition, error) \ + if (condition) { \ + dbgln_if(WEBGL_CONTEXT_DEBUG, "{}(): error {:#x}", __func__, error); \ + set_error(error); \ + return; \ + } + void WebGLRenderingContextBase::present() { if (!m_should_present) @@ -71,6 +78,15 @@ void WebGLRenderingContextBase::needs_to_present() m_canvas_element->layout_node()->set_needs_display(); } +void WebGLRenderingContextBase::set_error(GLenum error) +{ + auto context_error = m_context->gl_get_error(); + if (context_error != GL_NO_ERROR) + m_error = context_error; + else + m_error = error; +} + bool WebGLRenderingContextBase::is_context_lost() const { dbgln_if(WEBGL_CONTEXT_DEBUG, "WebGLRenderingContextBase::is_context_lost()"); @@ -210,6 +226,22 @@ void WebGLRenderingContextBase::front_face(GLenum mode) m_context->gl_front_face(mode); } +GLenum WebGLRenderingContextBase::get_error() +{ + dbgln_if(WEBGL_CONTEXT_DEBUG, "WebGLRenderingContextBase::get_error()"); + + // "If the context's webgl context lost flag is set, returns CONTEXT_LOST_WEBGL the first time this method is called. Afterward, returns NO_ERROR until the context has been restored." + // FIXME: The plan here is to make the context lost handler unconditionally set m_error to CONTEXT_LOST_WEBGL, which we currently do not have. + // The idea for the unconditional set is that any potentially error generating functions will not execute when the context is lost. + if (m_error != GL_NO_ERROR || m_context_lost) { + auto last_error = m_error; + m_error = GL_NO_ERROR; + return last_error; + } + + return m_context->gl_get_error(); +} + void WebGLRenderingContextBase::polygon_offset(GLfloat factor, GLfloat units) { if (m_context_lost) diff --git a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.h b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.h index ed3adfa01e..d5fe6313a8 100644 --- a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.h +++ b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.h @@ -46,6 +46,8 @@ public: void front_face(GLenum mode); + GLenum get_error(); + void polygon_offset(GLfloat factor, GLfloat units); void scissor(GLint x, GLint y, GLsizei width, GLsizei height); @@ -81,7 +83,10 @@ private: // - clear, drawArrays, or drawElements has been called while the drawing buffer is the currently bound framebuffer bool m_should_present { true }; + GLenum m_error { GL_NO_ERROR }; + void needs_to_present(); + void set_error(GLenum error); }; } diff --git a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.idl b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.idl index a850aa4af6..1e536e8817 100644 --- a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.idl +++ b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.idl @@ -41,6 +41,8 @@ interface mixin WebGLRenderingContextBase { undefined frontFace(GLenum mode); + GLenum getError(); + undefined polygonOffset(GLfloat factor, GLfloat units); undefined scissor(GLint x, GLint y, GLsizei width, GLsizei height);