diff --git a/src/main/cpp/CMakeLists.txt b/src/main/cpp/CMakeLists.txt index 98b3c83..7ce2ce3 100644 --- a/src/main/cpp/CMakeLists.txt +++ b/src/main/cpp/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.22.1) project("mobileglues") +enable_language(CXX) + set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -30,7 +32,7 @@ add_library(${CMAKE_PROJECT_NAME} SHARED gl/texture.c gl/drawing.c gl/mg.c - gl/buffer.c + gl/buffer.cpp gl/getter.c gl/glsl/glsl_for_es.cpp glx/lookup.c diff --git a/src/main/cpp/gl/buffer.c b/src/main/cpp/gl/buffer.cpp similarity index 54% rename from src/main/cpp/gl/buffer.c rename to src/main/cpp/gl/buffer.cpp index f39b1c0..73af27d 100644 --- a/src/main/cpp/gl/buffer.c +++ b/src/main/cpp/gl/buffer.cpp @@ -3,9 +3,12 @@ // #include "buffer.h" +#include #define DEBUG 0 +std::unordered_map g_active_mappings; + static GLenum get_binding_query(GLenum target) { switch(target) { case GL_ARRAY_BUFFER: return GL_ARRAY_BUFFER_BINDING; @@ -44,58 +47,55 @@ void* glMapBuffer(GLenum target, GLenum access) { } void* ptr = glMapBufferRange(target, 0, buffer_size, flags); if (!ptr) return NULL; - g_active_mapping.target = target; - g_active_mapping.buffer_id = (GLuint)current_buffer; - g_active_mapping.mapped_ptr = ptr; - g_active_mapping.size = buffer_size; - g_active_mapping.flags = flags; - g_active_mapping.is_dirty = (flags & GL_MAP_WRITE_BIT) ? GL_TRUE : GL_FALSE; + BufferMapping mapping; + mapping.target = target; + mapping.buffer_id = (GLuint)current_buffer; + mapping.mapped_ptr = ptr; + mapping.size = buffer_size; + mapping.flags = flags; + mapping.is_dirty = (flags & GL_MAP_WRITE_BIT) ? GL_TRUE : GL_FALSE; + g_active_mappings[current_buffer] = mapping; CHECK_GL_ERROR return ptr; } -static void force_unmap(GLenum target, GLuint original_buffer) { - GLint prev_buffer; - glGetIntegerv(get_binding_query(target), &prev_buffer); - GLuint temp_buffer; - glGenBuffers(1, &temp_buffer); - glBindBuffer(target, temp_buffer); - glBindBuffer(target, 0); - glDeleteBuffers(1, &temp_buffer); - if (target == GL_ARRAY_BUFFER) { - GLint prev_element_array; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prev_element_array); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_element_array); - } else { - GLint prev_array; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prev_array); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, prev_array); +GLboolean force_unmap() { + if (g_active_mappings.empty()) + return GL_FALSE; + + LOAD_GLES(glBindBuffer, void, GLenum target, GLuint buffer) + LOAD_GLES(glUnmapBuffer, GLboolean, GLenum target); + + for (auto& [buffer, binding]: g_active_mappings) { + GLint prev_buffer = 0; + GLenum binding_query = get_binding_query(binding.target); + glGetIntegerv(binding_query, &prev_buffer); + + gles_glBindBuffer(binding.target, binding.buffer_id); + GLboolean result = gles_glUnmapBuffer(binding.target); + gles_glBindBuffer(binding.target, prev_buffer); } - glBindBuffer(target, original_buffer); + + g_active_mappings.clear(); + + return GL_TRUE; } GLboolean glUnmapBuffer(GLenum target) { LOG() - if (g_active_mapping.mapped_ptr == NULL || - g_active_mapping.target != target || - g_active_mapping.buffer_id == 0) { - return GL_FALSE; - } - GLint prev_buffer; + GLint buffer; GLenum binding_query = get_binding_query(target); - glGetIntegerv(binding_query, &prev_buffer); + glGetIntegerv(binding_query, &buffer); - glBindBuffer(target, g_active_mapping.buffer_id); + if (buffer == 0) + return GL_FALSE; LOAD_GLES(glUnmapBuffer, GLboolean, GLenum target); GLboolean result = gles_glUnmapBuffer(target); - glBindBuffer(target, prev_buffer); + g_active_mappings.erase(buffer); - memset(&g_active_mapping, 0, sizeof(BufferMapping)); CHECK_GL_ERROR return result; } \ No newline at end of file diff --git a/src/main/cpp/gl/buffer.h b/src/main/cpp/gl/buffer.h index a33942a..72de549 100644 --- a/src/main/cpp/gl/buffer.h +++ b/src/main/cpp/gl/buffer.h @@ -12,10 +12,14 @@ #include "../gles/loader.h" #include "mg.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct { GLenum target; GLuint buffer_id; - void* mapped_ptr; + void *mapped_ptr; GLsizeiptr size; GLbitfield flags; GLboolean is_dirty; @@ -24,11 +28,17 @@ typedef struct { static BufferMapping g_active_mapping = {0}; static GLenum get_binding_query(GLenum target); -static void force_unmap(GLenum target, GLuint original_buffer); + +GLboolean force_unmap(); GLAPI GLAPIENTRY GLboolean glUnmapBuffer(GLenum target); + GLAPI GLAPIENTRY void *glMapBuffer(GLenum target, GLenum access); +#ifdef __cplusplus +} +#endif + #define MOBILEGLUES_BUFFER_H #endif //MOBILEGLUES_BUFFER_H diff --git a/src/main/cpp/gl/drawing.c b/src/main/cpp/gl/drawing.c index 9d69615..bcaa694 100644 --- a/src/main/cpp/gl/drawing.c +++ b/src/main/cpp/gl/drawing.c @@ -3,13 +3,14 @@ // #include "drawing.h" +#include "buffer.h" #define DEBUG 0 void glMultiDrawElementsBaseVertex( GLenum mode, GLsizei *counts, GLenum type, const void * const *indices, GLsizei primcount, const GLint * basevertex) { LOG(); - glUnmapBuffer(GL_ARRAY_BUFFER); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + + force_unmap(); for (int i = 0; i < primcount; i++) { if (counts[i] > 0)