From e537e2690a9a4af1217dd9703aa869da791ed991 Mon Sep 17 00:00:00 2001 From: Jesse Buhagiar Date: Fri, 23 Apr 2021 23:48:28 +1000 Subject: [PATCH] LibGL: Implement glGetError and underlying function This implements `glGetError` and correctly sets the state machine's error macro (similar to LibC `errno`) when an invalid operation is performed. This is reset on completion of a successful operation. --- Userland/Libraries/LibGL/GL/gl.h | 9 ++++ Userland/Libraries/LibGL/GLContext.h | 1 + Userland/Libraries/LibGL/GLUtils.cpp | 5 +++ .../Libraries/LibGL/SoftwareGLContext.cpp | 44 +++++++++++++++++-- Userland/Libraries/LibGL/SoftwareGLContext.h | 3 ++ 5 files changed, 58 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibGL/GL/gl.h b/Userland/Libraries/LibGL/GL/gl.h index e494cf092ae..132a103265c 100644 --- a/Userland/Libraries/LibGL/GL/gl.h +++ b/Userland/Libraries/LibGL/GL/gl.h @@ -37,6 +37,14 @@ extern "C" { #define GL_RENDERER 0x1F01 #define GL_VERSION 0x1F02 +// Error codes +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x500 +#define GL_INVALID_VALUE 0x501 +#define GL_INVALID_OPERATION 0x502 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x503 +#define GL_OUT_OF_MEMORY 0x504 + // // OpenGL typedefs // @@ -66,6 +74,7 @@ GLAPI void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf al GLAPI void glColor3f(GLfloat r, GLfloat g, GLfloat b); GLAPI void glEnd(); GLAPI void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal); +GLAPI GLenum glGetError(); GLAPI GLubyte* glGetString(GLenum name); GLAPI void glLoadIdentity(); GLAPI void glMatrixMode(GLenum mode); diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index 628e277f790..8e00018b25c 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -22,6 +22,7 @@ public: virtual void gl_color(GLdouble r, GLdouble g, GLdouble b, GLdouble a) = 0; virtual void gl_end() = 0; virtual void gl_frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val) = 0; + virtual GLenum gl_get_error() = 0; virtual GLubyte* gl_get_string(GLenum name) = 0; virtual void gl_load_identity() = 0; virtual void gl_matrix_mode(GLenum mode) = 0; diff --git a/Userland/Libraries/LibGL/GLUtils.cpp b/Userland/Libraries/LibGL/GLUtils.cpp index d128a534a1f..e17922be68b 100644 --- a/Userland/Libraries/LibGL/GLUtils.cpp +++ b/Userland/Libraries/LibGL/GLUtils.cpp @@ -29,3 +29,8 @@ void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { g_gl_context->gl_viewport(x, y, width, height); } + +GLenum glGetError() +{ + return g_gl_context->gl_get_error(); +} diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index bad3f8dc586..0ffb999170c 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -129,7 +129,13 @@ static void clip_triangle_against_frustum(Vector& in_vec) void SoftwareGLContext::gl_begin(GLenum mode) { + if (mode < GL_TRIANGLES || mode > GL_POLYGON) { + m_error = GL_INVALID_ENUM; + return; + } + m_current_draw_mode = mode; + m_error = GL_NO_ERROR; } void SoftwareGLContext::gl_clear(GLbitfield mask) @@ -141,19 +147,22 @@ void SoftwareGLContext::gl_clear(GLbitfield mask) uint64_t color = r << 16 | g << 8 | b; (void)(color); + m_error = GL_NO_ERROR; } else { - // set gl error here!? + m_error = GL_INVALID_ENUM; } } void SoftwareGLContext::gl_clear_color(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { m_clear_color = { red, green, blue, alpha }; + m_error = GL_NO_ERROR; } void SoftwareGLContext::gl_color(GLdouble r, GLdouble g, GLdouble b, GLdouble a) { m_current_vertex_color = { (float)r, (float)g, (float)b, (float)a }; + m_error = GL_NO_ERROR; } void SoftwareGLContext::gl_end() @@ -218,7 +227,8 @@ void SoftwareGLContext::gl_end() triangle_list.append(triangle); } } else { - VERIFY_NOT_REACHED(); + m_error = GL_INVALID_ENUM; + return; } // Now let's transform each triangle and send that to the GPU @@ -374,6 +384,8 @@ void SoftwareGLContext::gl_end() triangle_list.clear(); processed_triangles.clear(); vertex_list.clear(); + + m_error = GL_NO_ERROR; } void SoftwareGLContext::gl_frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val) @@ -398,6 +410,13 @@ void SoftwareGLContext::gl_frustum(GLdouble left, GLdouble right, GLdouble botto dbgln_if(GL_DEBUG, "glFrustum(): frustum created with curr_matrix_mode == GL_MODELVIEW!!!"); m_projection_matrix = m_model_view_matrix * frustum; } + + m_error = GL_NO_ERROR; +} + +GLenum SoftwareGLContext::gl_get_error() +{ + return m_error; } GLubyte* SoftwareGLContext::gl_get_string(GLenum name) @@ -414,7 +433,7 @@ GLubyte* SoftwareGLContext::gl_get_string(GLenum name) break; } - // FIXME: Set glError to GL_INVALID_ENUM here + m_error = GL_INVALID_ENUM; return nullptr; } @@ -426,12 +445,19 @@ void SoftwareGLContext::gl_load_identity() m_model_view_matrix = FloatMatrix4x4::identity(); else VERIFY_NOT_REACHED(); + + m_error = GL_NO_ERROR; } void SoftwareGLContext::gl_matrix_mode(GLenum mode) { - VERIFY(mode == GL_MODELVIEW || mode == GL_PROJECTION); + if (mode < GL_MODELVIEW || mode > GL_PROJECTION) { + m_error = GL_INVALID_ENUM; + return; + } + m_current_matrix_mode = mode; + m_error = GL_NO_ERROR; } void SoftwareGLContext::gl_push_matrix() @@ -449,6 +475,8 @@ void SoftwareGLContext::gl_push_matrix() dbgln_if(GL_DEBUG, "glPushMatrix(): Attempt to push matrix with invalid matrix mode {})", m_current_matrix_mode); return; } + + m_error = GL_NO_ERROR; } void SoftwareGLContext::gl_pop_matrix() @@ -467,6 +495,8 @@ void SoftwareGLContext::gl_pop_matrix() dbgln_if(GL_DEBUG, "glPopMatrix(): Attempt to pop matrix with invalid matrix mode, {}", m_current_matrix_mode); return; } + + m_error = GL_NO_ERROR; } void SoftwareGLContext::gl_rotate(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) @@ -479,6 +509,8 @@ void SoftwareGLContext::gl_rotate(GLdouble angle, GLdouble x, GLdouble y, GLdoub m_model_view_matrix = m_model_view_matrix * rotation_mat; else if (m_current_matrix_mode == GL_PROJECTION) m_projection_matrix = m_projection_matrix * rotation_mat; + + m_error = GL_NO_ERROR; } void SoftwareGLContext::gl_translate(GLdouble x, GLdouble y, GLdouble z) @@ -488,6 +520,8 @@ void SoftwareGLContext::gl_translate(GLdouble x, GLdouble y, GLdouble z) } else if (m_current_matrix_mode == GL_PROJECTION) { m_projection_matrix = m_projection_matrix * FloatMatrix4x4::translate({ (float)x, (float)y, (float)z }); } + + m_error = GL_NO_ERROR; } void SoftwareGLContext::gl_vertex(GLdouble x, GLdouble y, GLdouble z, GLdouble w) @@ -509,6 +543,7 @@ void SoftwareGLContext::gl_vertex(GLdouble x, GLdouble y, GLdouble z, GLdouble w vertex.v = 0.0f; vertex_list.append(vertex); + m_error = GL_NO_ERROR; } void SoftwareGLContext::gl_viewport(GLint x, GLint y, GLsizei width, GLsizei height) @@ -517,6 +552,7 @@ void SoftwareGLContext::gl_viewport(GLint x, GLint y, GLsizei width, GLsizei hei (void)(y); (void)(width); (void)(height); + m_error = GL_NO_ERROR; } } diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h index a8c1d7df8bc..7ae19b9a42b 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -22,6 +22,7 @@ public: virtual void gl_color(GLdouble r, GLdouble g, GLdouble b, GLdouble a) override; virtual void gl_end() override; virtual void gl_frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val) override; + virtual GLenum gl_get_error() override; virtual GLubyte* gl_get_string(GLenum name) override; virtual void gl_load_identity() override; virtual void gl_matrix_mode(GLenum mode) override; @@ -49,6 +50,8 @@ private: Vector vertex_list; Vector triangle_list; Vector processed_triangles; + + GLenum m_error = GL_NO_ERROR; }; }