Serenity Operating System
at master 108 lines 3.6 kB view raw
1/* 2 * Copyright (c) 2022, Jelle Raaijmakers <jelle@gmta.nl> 3 * Copyright (c) 2022, cflip <cflip@cflip.net> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#include <LibGL/GLContext.h> 9 10namespace GL { 11 12void GLContext::gl_bind_buffer(GLenum target, GLuint buffer) 13{ 14 RETURN_WITH_ERROR_IF(target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER, GL_INVALID_ENUM); 15 RETURN_WITH_ERROR_IF(!m_buffer_name_allocator.has_allocated_name(buffer), GL_INVALID_VALUE); 16 17 auto& target_buffer = target == GL_ELEMENT_ARRAY_BUFFER ? m_element_array_buffer : m_array_buffer; 18 target_buffer = nullptr; 19 20 if (buffer != 0) { 21 auto it = m_allocated_buffers.find(buffer); 22 if (it != m_allocated_buffers.end()) { 23 auto buffer_object = it->value; 24 if (!buffer_object.is_null()) { 25 target_buffer = buffer_object; 26 } 27 } 28 29 if (!target_buffer) { 30 target_buffer = adopt_ref(*new Buffer()); 31 m_allocated_buffers.set(buffer, target_buffer); 32 } 33 } 34} 35 36void GLContext::gl_buffer_data(GLenum target, GLsizeiptr size, void const* data, GLenum usage) 37{ 38 RETURN_WITH_ERROR_IF(usage != GL_STREAM_DRAW 39 && usage != GL_STREAM_READ 40 && usage != GL_STREAM_COPY 41 && usage != GL_STATIC_DRAW 42 && usage != GL_STATIC_READ 43 && usage != GL_STATIC_COPY 44 && usage != GL_DYNAMIC_DRAW 45 && usage != GL_DYNAMIC_READ 46 && usage != GL_DYNAMIC_COPY, 47 GL_INVALID_ENUM); 48 RETURN_WITH_ERROR_IF(target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER, GL_INVALID_ENUM); 49 50 auto& target_buffer = target == GL_ELEMENT_ARRAY_BUFFER ? m_element_array_buffer : m_array_buffer; 51 RETURN_WITH_ERROR_IF(!target_buffer, GL_INVALID_OPERATION); 52 53 RETURN_WITH_ERROR_IF(target_buffer->set_data(data, size).is_error(), GL_OUT_OF_MEMORY); 54} 55 56void GLContext::gl_buffer_sub_data(GLenum target, GLintptr offset, GLsizeiptr size, void const* data) 57{ 58 RETURN_WITH_ERROR_IF(target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER, GL_INVALID_ENUM); 59 RETURN_WITH_ERROR_IF(offset < 0, GL_INVALID_VALUE); 60 // FIXME: Support buffer storage mutability flags. 61 62 auto& target_buffer = target == GL_ELEMENT_ARRAY_BUFFER ? m_element_array_buffer : m_array_buffer; 63 RETURN_WITH_ERROR_IF(!target_buffer, GL_INVALID_OPERATION); 64 RETURN_WITH_ERROR_IF(static_cast<size_t>(offset + size) > target_buffer->size(), GL_INVALID_VALUE); 65 66 target_buffer->replace_data(data, offset, size); 67} 68 69void GLContext::gl_delete_buffers(GLsizei n, GLuint const* buffers) 70{ 71 RETURN_WITH_ERROR_IF(n < 0, GL_INVALID_VALUE); 72 73 for (auto i = 0; i < n; i++) { 74 GLuint name = buffers[i]; 75 if (name == 0) 76 continue; 77 78 auto buffer_object = m_allocated_buffers.find(name); 79 if (buffer_object == m_allocated_buffers.end() || buffer_object->value.is_null()) 80 continue; 81 82 Buffer* buffer = buffer_object->value; 83 84 if (m_array_buffer == buffer) 85 m_array_buffer = nullptr; 86 87 if (m_element_array_buffer == buffer) 88 m_element_array_buffer = nullptr; 89 90 m_buffer_name_allocator.free(name); 91 m_allocated_buffers.remove(name); 92 } 93} 94 95void GLContext::gl_gen_buffers(GLsizei n, GLuint* buffers) 96{ 97 RETURN_WITH_ERROR_IF(n < 0, GL_INVALID_VALUE); 98 99 m_buffer_name_allocator.allocate(n, buffers); 100 101 // Initialize all buffer names with a nullptr 102 for (auto i = 0; i < n; ++i) { 103 GLuint name = buffers[i]; 104 m_allocated_buffers.set(name, nullptr); 105 } 106} 107 108}