diff --git a/Userland/Libraries/LibGL/GL/gl.h b/Userland/Libraries/LibGL/GL/gl.h index 12a69742dc..79aeb5be76 100644 --- a/Userland/Libraries/LibGL/GL/gl.h +++ b/Userland/Libraries/LibGL/GL/gl.h @@ -147,6 +147,9 @@ extern "C" { #define GL_INT 0x1404 #define GL_UNSIGNED_INT 0x1405 #define GL_FLOAT 0x1406 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 #define GL_DOUBLE 0x140A // Format enums @@ -388,6 +391,7 @@ GLAPI void glCullFace(GLenum mode); GLAPI void glFrontFace(GLenum mode); GLAPI GLuint glGenLists(GLsizei range); GLAPI void glCallList(GLuint list); +GLAPI void glCallLists(GLsizei n, GLenum type, void const* lists); GLAPI void glDeleteLists(GLuint list, GLsizei range); GLAPI void glEndList(void); GLAPI void glNewList(GLuint list, GLenum mode); diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index a2ffa0989f..ba170a2cae 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -48,6 +48,7 @@ public: virtual void gl_cull_face(GLenum) = 0; virtual GLuint gl_gen_lists(GLsizei range) = 0; virtual void gl_call_list(GLuint list) = 0; + virtual void gl_call_lists(GLsizei n, GLenum type, void const* lists) = 0; virtual void gl_delete_lists(GLuint list, GLsizei range) = 0; virtual void gl_end_list(void) = 0; virtual void gl_new_list(GLuint list, GLenum mode) = 0; diff --git a/Userland/Libraries/LibGL/GLLists.cpp b/Userland/Libraries/LibGL/GLLists.cpp index 06ff3cc863..bf6fe17bdf 100644 --- a/Userland/Libraries/LibGL/GLLists.cpp +++ b/Userland/Libraries/LibGL/GLLists.cpp @@ -19,6 +19,11 @@ void glCallList(GLuint list) return g_gl_context->gl_call_list(list); } +void glCallLists(GLsizei n, GLenum type, void const* lists) +{ + return g_gl_context->gl_call_lists(n, type, lists); +} + void glDeleteLists(GLuint list, GLsizei range) { return g_gl_context->gl_delete_lists(list, range); diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index 2af62ab289..323850811e 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -868,19 +868,9 @@ GLuint SoftwareGLContext::gl_gen_lists(GLsizei range) return initial_entry + 1; } -void SoftwareGLContext::gl_call_list(GLuint list) +void SoftwareGLContext::invoke_list(size_t list_index) { - if (m_gl_call_depth > max_allowed_gl_call_depth) - return; - - APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_call_list, list); - - if (m_listings.size() < list) - return; - - TemporaryChange change { m_gl_call_depth, m_gl_call_depth + 1 }; - - auto& listing = m_listings[list - 1]; + auto& listing = m_listings[list_index - 1]; for (auto& entry : listing.entries) { entry.function.visit([&](auto& function) { entry.arguments.visit([&](auto& arguments) { @@ -896,6 +886,81 @@ void SoftwareGLContext::gl_call_list(GLuint list) } } +void SoftwareGLContext::gl_call_list(GLuint list) +{ + if (m_gl_call_depth > max_allowed_gl_call_depth) + return; + + APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_call_list, list); + + if (m_listings.size() < list) + return; + + TemporaryChange change { m_gl_call_depth, m_gl_call_depth + 1 }; + + invoke_list(list); +} + +void SoftwareGLContext::gl_call_lists(GLsizei n, GLenum type, void const* lists) +{ + if (m_gl_call_depth > max_allowed_gl_call_depth) + return; + + APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_call_lists, n, type, lists); + + RETURN_WITH_ERROR_IF(n < 0, GL_INVALID_VALUE); + RETURN_WITH_ERROR_IF(!(type == GL_BYTE + || type == GL_UNSIGNED_BYTE + || type == GL_SHORT + || type == GL_UNSIGNED_SHORT + || type == GL_INT + || type == GL_UNSIGNED_INT + || type == GL_FLOAT + || type == GL_2_BYTES + || type == GL_3_BYTES + || type == GL_4_BYTES), + GL_INVALID_ENUM); + + TemporaryChange change { m_gl_call_depth, m_gl_call_depth + 1 }; + + auto invoke_all_lists = [&](T const* lists) { + for (int i = 0; i < n; ++i) { + auto list = static_cast(lists[i]); + invoke_list(list); + } + }; + switch (type) { + case GL_BYTE: + invoke_all_lists(static_cast(lists)); + break; + case GL_UNSIGNED_BYTE: + invoke_all_lists(static_cast(lists)); + break; + case GL_SHORT: + invoke_all_lists(static_cast(lists)); + break; + case GL_UNSIGNED_SHORT: + invoke_all_lists(static_cast(lists)); + break; + case GL_INT: + invoke_all_lists(static_cast(lists)); + break; + case GL_UNSIGNED_INT: + invoke_all_lists(static_cast(lists)); + break; + case GL_FLOAT: + invoke_all_lists(static_cast(lists)); + break; + case GL_2_BYTES: + case GL_3_BYTES: + case GL_4_BYTES: + dbgln("SoftwareGLContext FIXME: unimplemented glCallLists() with type {}", type); + break; + default: + VERIFY_NOT_REACHED(); + } +} + void SoftwareGLContext::gl_delete_lists(GLuint list, GLsizei range) { if (m_listings.size() < list || m_listings.size() <= list + range) diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h index 611e0298fd..c99c3fe91a 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -59,6 +59,7 @@ public: virtual void gl_cull_face(GLenum) override; virtual GLuint gl_gen_lists(GLsizei range) override; virtual void gl_call_list(GLuint list) override; + virtual void gl_call_lists(GLsizei n, GLenum type, void const* lists) override; virtual void gl_delete_lists(GLuint list, GLsizei range) override; virtual void gl_end_list(void) override; virtual void gl_new_list(GLuint list, GLenum mode) override; @@ -122,6 +123,7 @@ private: template void get_floating_point(GLenum pname, T* params); + void invoke_list(size_t list_index); [[nodiscard]] bool should_append_to_listing() const { return m_current_listing_index.has_value(); } [[nodiscard]] bool should_execute_after_appending_to_listing() const { return m_current_listing_index.has_value() && m_current_listing_index->mode == GL_COMPILE_AND_EXECUTE; } @@ -228,6 +230,7 @@ private: decltype(&SoftwareGLContext::gl_front_face), decltype(&SoftwareGLContext::gl_cull_face), decltype(&SoftwareGLContext::gl_call_list), + decltype(&SoftwareGLContext::gl_call_lists), decltype(&SoftwareGLContext::gl_blend_func), decltype(&SoftwareGLContext::gl_shade_model), decltype(&SoftwareGLContext::gl_alpha_func),