瀏覽代碼

LibGL: Implement `glCallLists`

Jelle Raaijmakers 3 年之前
父節點
當前提交
1056bac49a

+ 4 - 0
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);

+ 1 - 0
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;

+ 5 - 0
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);

+ 77 - 12
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 = [&]<typename T>(T const* lists) {
+        for (int i = 0; i < n; ++i) {
+            auto list = static_cast<size_t>(lists[i]);
+            invoke_list(list);
+        }
+    };
+    switch (type) {
+    case GL_BYTE:
+        invoke_all_lists(static_cast<GLbyte const*>(lists));
+        break;
+    case GL_UNSIGNED_BYTE:
+        invoke_all_lists(static_cast<GLubyte const*>(lists));
+        break;
+    case GL_SHORT:
+        invoke_all_lists(static_cast<GLshort const*>(lists));
+        break;
+    case GL_UNSIGNED_SHORT:
+        invoke_all_lists(static_cast<GLushort const*>(lists));
+        break;
+    case GL_INT:
+        invoke_all_lists(static_cast<GLint const*>(lists));
+        break;
+    case GL_UNSIGNED_INT:
+        invoke_all_lists(static_cast<GLuint const*>(lists));
+        break;
+    case GL_FLOAT:
+        invoke_all_lists(static_cast<GLfloat const*>(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)

+ 3 - 0
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<typename T>
     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),