Prechádzať zdrojové kódy

LibGL: Add Texture Name Allocation

Texture names can now be allocated via
`glGenTextures` and deallocated via `glDeleteTextures`.
Jesse Buhagiar 4 rokov pred
rodič
commit
21dff6d40b

+ 2 - 0
Userland/Libraries/LibGL/CMakeLists.txt

@@ -1,4 +1,5 @@
 set(SOURCES
+    Tex/NameAllocator.cpp
     Clipper.cpp
     GLBlend.cpp
     GLColor.cpp
@@ -6,6 +7,7 @@ set(SOURCES
     GLLights.cpp
     GLLists.cpp
     GLMat.cpp
+    GLTexture.cpp
     GLUtils.cpp
     GLVert.cpp
     SoftwareGLContext.cpp

+ 2 - 0
Userland/Libraries/LibGL/GL/gl.h

@@ -180,8 +180,10 @@ GLAPI void glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
 GLAPI void glColor4fv(const GLfloat* v);
 GLAPI void glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a);
 GLAPI void glColor4ubv(const GLubyte* v);
+GLAPI void glDeleteTextures(GLsizei n, const GLuint* textures);
 GLAPI void glEnd();
 GLAPI void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal);
+GLAPI void glGenTextures(GLsizei n, GLuint* textures);
 GLAPI GLenum glGetError();
 GLAPI GLubyte* glGetString(GLenum name);
 GLAPI void glLoadIdentity();

+ 2 - 0
Userland/Libraries/LibGL/GLContext.h

@@ -23,8 +23,10 @@ public:
     virtual void gl_clear_color(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = 0;
     virtual void gl_clear_depth(GLdouble depth) = 0;
     virtual void gl_color(GLdouble r, GLdouble g, GLdouble b, GLdouble a) = 0;
+    virtual void gl_delete_textures(GLsizei n, const GLuint* textures) = 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 void gl_gen_textures(GLsizei n, GLuint* textures) = 0;
     virtual GLenum gl_get_error() = 0;
     virtual GLubyte* gl_get_string(GLenum name) = 0;
     virtual void gl_load_identity() = 0;

+ 20 - 0
Userland/Libraries/LibGL/GLTexture.cpp

@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include "GLContext.h"
+#include <LibGL/GL/gl.h>
+
+extern GL::GLContext* g_gl_context;
+
+void glGenTextures(GLsizei n, GLuint* textures)
+{
+    g_gl_context->gl_gen_textures(n, textures);
+}
+
+void glDeleteTextures(GLsizei n, const GLuint* textures)
+{
+    g_gl_context->gl_delete_textures(n, textures);
+}

+ 30 - 0
Userland/Libraries/LibGL/SoftwareGLContext.cpp

@@ -742,6 +742,36 @@ void SoftwareGLContext::gl_disable(GLenum capability)
         m_rasterizer.set_options(rasterizer_options);
 }
 
+void SoftwareGLContext::gl_gen_textures(GLsizei n, GLuint* textures)
+{
+    if (n < 0) {
+        m_error = GL_INVALID_VALUE;
+        return;
+    }
+
+    if (m_in_draw_state) {
+        m_error = GL_INVALID_OPERATION;
+        return;
+    }
+
+    m_name_allocator.allocate(n, textures);
+}
+
+void SoftwareGLContext::gl_delete_textures(GLsizei n, const GLuint* textures)
+{
+    if (n < 0) {
+        m_error = GL_INVALID_VALUE;
+        return;
+    }
+
+    if (m_in_draw_state) {
+        m_error = GL_INVALID_OPERATION;
+        return;
+    }
+
+    m_name_allocator.free(n, textures);
+}
+
 void SoftwareGLContext::gl_front_face(GLenum face)
 {
     APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_front_face, face);

+ 3 - 0
Userland/Libraries/LibGL/SoftwareGLContext.h

@@ -29,8 +29,10 @@ public:
     virtual void gl_clear_color(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) override;
     virtual void gl_clear_depth(GLdouble depth) override;
     virtual void gl_color(GLdouble r, GLdouble g, GLdouble b, GLdouble a) override;
+    virtual void gl_delete_textures(GLsizei n, const GLuint* textures) 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 void gl_gen_textures(GLsizei n, GLuint* textures) override;
     virtual GLenum gl_get_error() override;
     virtual GLubyte* gl_get_string(GLenum name) override;
     virtual void gl_load_identity() override;
@@ -124,6 +126,7 @@ private:
     NonnullRefPtr<Gfx::Bitmap> m_frontbuffer;
 
     Clipper m_clipper;
+    TextureNameAllocator m_name_allocator;
 
     SoftwareRasterizer m_rasterizer;
 

+ 33 - 0
Userland/Libraries/LibGL/Tex/NameAllocator.cpp

@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibGL/Tex/NameAllocator.h>
+
+namespace GL {
+
+void TextureNameAllocator::allocate(GLsizei count, GLuint* textures)
+{
+    for (auto i = 0; i < count; ++i) {
+        if (!m_free_texture_names.is_empty()) {
+            textures[i] = m_free_texture_names.top();
+            m_free_texture_names.pop();
+        } else {
+            // We're out of free previously allocated names. Let's allocate a new contiguous amount from the
+            // last known texture name
+            textures[i] = m_last_texture_id++;
+        }
+    }
+}
+
+void TextureNameAllocator::free(GLsizei count, const GLuint* textures)
+{
+    size_t tex_array_index = 0;
+
+    while (count-- > 0)
+        m_free_texture_names.push(textures[tex_array_index++]);
+}
+
+}

+ 26 - 0
Userland/Libraries/LibGL/Tex/NameAllocator.h

@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Stack.h>
+#include <LibGL/GL/gl.h>
+
+namespace GL {
+
+class TextureNameAllocator {
+public:
+    TextureNameAllocator() = default;
+
+    void allocate(GLsizei count, GLuint* textures);
+    void free(GLsizei count, const GLuint* textures);
+
+private:
+    Stack<GLuint, 512> m_free_texture_names;
+    GLuint m_last_texture_id { 1 };
+};
+
+}