Buffer.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. #include <AK/Debug.h>
  8. #include <LibGL/GLContext.h>
  9. namespace GL {
  10. void GLContext::gl_bind_buffer(GLenum target, GLuint buffer)
  11. {
  12. RETURN_WITH_ERROR_IF(target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER, GL_INVALID_ENUM);
  13. RETURN_WITH_ERROR_IF(!m_buffer_name_allocator.has_allocated_name(buffer), GL_INVALID_VALUE);
  14. auto& target_buffer = target == GL_ELEMENT_ARRAY_BUFFER ? m_element_array_buffer : m_array_buffer;
  15. target_buffer = nullptr;
  16. if (buffer != 0) {
  17. auto it = m_allocated_buffers.find(buffer);
  18. if (it != m_allocated_buffers.end()) {
  19. auto buffer_object = it->value;
  20. if (!buffer_object.is_null()) {
  21. target_buffer = buffer_object;
  22. }
  23. }
  24. if (!target_buffer) {
  25. target_buffer = adopt_ref(*new Buffer());
  26. m_allocated_buffers.set(buffer, target_buffer);
  27. }
  28. }
  29. }
  30. void GLContext::gl_buffer_data(GLenum target, GLsizeiptr size, void const* data, GLenum usage)
  31. {
  32. RETURN_WITH_ERROR_IF(usage != GL_STREAM_DRAW
  33. && usage != GL_STREAM_READ
  34. && usage != GL_STREAM_COPY
  35. && usage != GL_STATIC_DRAW
  36. && usage != GL_STATIC_READ
  37. && usage != GL_STATIC_COPY
  38. && usage != GL_DYNAMIC_DRAW
  39. && usage != GL_DYNAMIC_READ
  40. && usage != GL_DYNAMIC_COPY,
  41. GL_INVALID_ENUM);
  42. RETURN_WITH_ERROR_IF(target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER, GL_INVALID_ENUM);
  43. auto& target_buffer = target == GL_ELEMENT_ARRAY_BUFFER ? m_element_array_buffer : m_array_buffer;
  44. RETURN_WITH_ERROR_IF(!target_buffer, GL_INVALID_OPERATION);
  45. // FIXME: Report GL_OUT_OF_MEMORY or other errors as needed here
  46. MUST(target_buffer->set_data(data, size));
  47. }
  48. void GLContext::gl_buffer_sub_data(GLenum target, GLintptr offset, GLsizeiptr size, void const* data)
  49. {
  50. RETURN_WITH_ERROR_IF(target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER, GL_INVALID_ENUM);
  51. RETURN_WITH_ERROR_IF(offset < 0, GL_INVALID_VALUE);
  52. // FIXME: Support buffer storage mutability flags.
  53. auto& target_buffer = target == GL_ELEMENT_ARRAY_BUFFER ? m_element_array_buffer : m_array_buffer;
  54. RETURN_WITH_ERROR_IF(!target_buffer, GL_INVALID_OPERATION);
  55. RETURN_WITH_ERROR_IF((offset + size) > target_buffer->size(), GL_INVALID_VALUE);
  56. target_buffer->replace_data(data, offset, size);
  57. }
  58. void GLContext::gl_delete_buffers(GLsizei n, GLuint const* buffers)
  59. {
  60. RETURN_WITH_ERROR_IF(n < 0, GL_INVALID_VALUE);
  61. for (auto i = 0; i < n; i++) {
  62. GLuint name = buffers[i];
  63. if (name == 0)
  64. continue;
  65. auto buffer_object = m_allocated_buffers.find(name);
  66. if (buffer_object == m_allocated_buffers.end() || buffer_object->value.is_null())
  67. continue;
  68. Buffer* buffer = buffer_object->value;
  69. if (m_array_buffer == buffer)
  70. m_array_buffer = nullptr;
  71. if (m_element_array_buffer == buffer)
  72. m_element_array_buffer = nullptr;
  73. m_buffer_name_allocator.free(name);
  74. m_allocated_buffers.remove(name);
  75. }
  76. }
  77. void GLContext::gl_gen_buffers(GLsizei n, GLuint* buffers)
  78. {
  79. RETURN_WITH_ERROR_IF(n < 0, GL_INVALID_VALUE);
  80. m_buffer_name_allocator.allocate(n, buffers);
  81. // Initialize all buffer names with a nullptr
  82. for (auto i = 0; i < n; ++i) {
  83. GLuint name = buffers[i];
  84. m_allocated_buffers.set(name, nullptr);
  85. }
  86. }
  87. }