Commit: 328a47fa2cc6f8e76ac83d6cba14b9bd24c0dd52
Author: Mike Erwin
Date:   Tue Nov 29 00:03:54 2016 -0500
Branches: blender2.8
https://developer.blender.org/rB328a47fa2cc6f8e76ac83d6cba14b9bd24c0dd52

Gawain: manage GL buffer IDs in a thread-safe way

Needed because deps graph can destroy objects from any thread. We ran into the 
same problem & solved it in GPU_buffers.

Implemented in C++11 since it provides the needed machinery. The interface is 
in C like the rest of Gawain.

===================================================================

M       source/blender/gpu/CMakeLists.txt
A       source/blender/gpu/gawain/buffer_id.cpp
A       source/blender/gpu/gawain/buffer_id.h

===================================================================

diff --git a/source/blender/gpu/CMakeLists.txt 
b/source/blender/gpu/CMakeLists.txt
index b66085b..5643400 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -70,6 +70,8 @@ set(SRC
        gawain/attrib_binding.h
        gawain/batch.c
        gawain/batch.h
+       gawain/buffer_id.h
+       gawain/buffer_id.cpp
        gawain/common.h
        gawain/element.c
        gawain/element.h
diff --git a/source/blender/gpu/gawain/buffer_id.cpp 
b/source/blender/gpu/gawain/buffer_id.cpp
new file mode 100644
index 0000000..a7b8d7a
--- /dev/null
+++ b/source/blender/gpu/gawain/buffer_id.cpp
@@ -0,0 +1,116 @@
+
+// Gawain buffer IDs
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public 
License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at 
https://mozilla.org/MPL/2.0/.#include "buffer_id.h"
+
+#include "buffer_id.h"
+#include <mutex>
+#include <vector>
+
+#define ORPHAN_DEBUG 0
+
+#if ORPHAN_DEBUG
+       #include <cstdio>
+#endif
+
+static std::vector<GLuint> orphaned_buffer_ids;
+static std::vector<GLuint> orphaned_vao_ids;
+
+static std::mutex orphan_mutex;
+
+extern "C" {
+extern int BLI_thread_is_main(void); // Blender-specific function
+}
+
+static bool thread_is_main()
+       {
+       // "main" here means the GL context's thread
+       return BLI_thread_is_main();
+       }
+
+GLuint buffer_id_alloc()
+       {
+#if TRUST_NO_ONE
+       assert(thread_is_main());
+#endif
+
+       // delete orphaned IDs
+       orphan_mutex.lock();
+       if (!orphaned_buffer_ids.empty())
+               {
+               const auto orphaned_buffer_ct = 
(unsigned)orphaned_buffer_ids.size();
+#if ORPHAN_DEBUG
+               printf("deleting %u orphaned VBO%s\n", orphaned_buffer_ct, 
orphaned_buffer_ct == 1 ? "" : "s");
+#endif
+               glDeleteBuffers(orphaned_buffer_ct, orphaned_buffer_ids.data());
+               orphaned_buffer_ids.clear();
+               }
+       orphan_mutex.unlock();
+
+       GLuint new_buffer_id;
+       glGenBuffers(1, &new_buffer_id);
+       return new_buffer_id;
+       }
+
+void buffer_id_free(GLuint buffer_id)
+       {
+       if (thread_is_main())
+               glDeleteBuffers(1, &buffer_id);
+       else
+               {
+               // add this ID to the orphaned list
+               orphan_mutex.lock();
+#if ORPHAN_DEBUG
+               printf("orphaning VBO %u\n", buffer_id);
+#endif
+               orphaned_buffer_ids.emplace_back(buffer_id);
+               orphan_mutex.unlock();
+               }
+       }
+
+GLuint vao_id_alloc()
+       {
+#if TRUST_NO_ONE
+       assert(thread_is_main());
+#endif
+
+       GLuint new_vao_id;
+
+       // delete orphaned IDs
+       orphan_mutex.lock();
+       if (!orphaned_vao_ids.empty())
+               {
+               const auto orphaned_vao_ct = (unsigned)orphaned_vao_ids.size();
+#if ORPHAN_DEBUG
+               printf("deleting %u orphaned VAO%s\n", orphaned_vao_ct, 
orphaned_vao_ct == 1 ? "" : "s");
+#endif
+               glDeleteVertexArrays(orphaned_vao_ct, orphaned_vao_ids.data());
+               orphaned_vao_ids.clear();
+               }
+       orphan_mutex.unlock();
+
+       glGenVertexArrays(1, &new_vao_id);
+       return new_vao_id;
+       }
+
+void vao_id_free(GLuint vao_id)
+       {
+       if (thread_is_main())
+               glDeleteVertexArrays(1, &vao_id);
+       else
+               {
+               // add this ID to the orphaned list
+               orphan_mutex.lock();
+#if ORPHAN_DEBUG
+               printf("orphaning VAO %u\n", vao_id);
+#endif
+               orphaned_vao_ids.emplace_back(vao_id);
+               orphan_mutex.unlock();
+               }
+       }
diff --git a/source/blender/gpu/gawain/buffer_id.h 
b/source/blender/gpu/gawain/buffer_id.h
new file mode 100644
index 0000000..3f67458
--- /dev/null
+++ b/source/blender/gpu/gawain/buffer_id.h
@@ -0,0 +1,34 @@
+
+// Gawain buffer IDs
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public 
License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at 
https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+// Manage GL buffer IDs in a thread-safe way
+// Use these instead of glGenBuffers & its friends
+// - alloc must be called from main thread
+// - free can be called from any thread
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "common.h"
+
+GLuint buffer_id_alloc(void);
+void buffer_id_free(GLuint buffer_id);
+
+GLuint vao_id_alloc(void);
+void vao_id_free(GLuint vao_id);
+
+
+#ifdef __cplusplus
+}
+#endif

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to