Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/gawain')
-rw-r--r--intern/gawain/gawain/gwn_context.h34
-rw-r--r--intern/gawain/gawain/gwn_vertex_array_id.h34
-rw-r--r--intern/gawain/src/gwn_vertex_array_id.cpp136
3 files changed, 204 insertions, 0 deletions
diff --git a/intern/gawain/gawain/gwn_context.h b/intern/gawain/gawain/gwn_context.h
new file mode 100644
index 00000000000..3addce762b3
--- /dev/null
+++ b/intern/gawain/gawain/gwn_context.h
@@ -0,0 +1,34 @@
+
+// Gawain context
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2018 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
+
+// This interface allow Gawain to manage VAOs for mutiple context and threads.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gwn_common.h"
+#include "gwn_batch.h"
+#include "gwn_shader_interface.h"
+
+typedef struct Gwn_Context Gwn_Context;
+
+Gwn_Context* GWN_context_create(void);
+void GWN_context_discard(Gwn_Context*);
+
+void GWN_context_active_set(Gwn_Context*);
+Gwn_Context* GWN_context_active_get(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/intern/gawain/gawain/gwn_vertex_array_id.h b/intern/gawain/gawain/gwn_vertex_array_id.h
new file mode 100644
index 00000000000..6d2a059b9bd
--- /dev/null
+++ b/intern/gawain/gawain/gwn_vertex_array_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 2018 Mike Erwin, Clément Foucault
+//
+// 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 vertex array IDs in a thread-safe way
+// Use these instead of glGenBuffers & its friends
+// - alloc must be called from a thread that is bound
+// to the context that will be used for drawing with
+// this vao.
+// - free can be called from any thread
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gwn_common.h"
+#include "gwn_context.h"
+
+GLuint GWN_vao_default(void);
+GLuint GWN_vao_alloc_new(void);
+void GWN_vao_free_new(GLuint vao_id, Gwn_Context*);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/intern/gawain/src/gwn_vertex_array_id.cpp b/intern/gawain/src/gwn_vertex_array_id.cpp
new file mode 100644
index 00000000000..602c1c4919c
--- /dev/null
+++ b/intern/gawain/src/gwn_vertex_array_id.cpp
@@ -0,0 +1,136 @@
+
+// Gawain vertex array IDs
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin, Clément Foucault
+//
+// 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 "gwn_vertex_array_id.h"
+#include "gwn_context.h"
+#include <vector>
+#include <string.h>
+#include <pthread.h>
+#include <mutex>
+
+#if TRUST_NO_ONE
+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();
+ }
+#endif
+
+struct Gwn_Context {
+ GLuint default_vao;
+ std::vector<GLuint> orphaned_vertarray_ids;
+ std::mutex orphans_mutex; // todo: try spinlock instead
+#if TRUST_NO_ONE
+ pthread_t thread; // Thread on which this context is active.
+#endif
+};
+
+static thread_local Gwn_Context* active_ctx = NULL;
+
+static void clear_orphans(Gwn_Context* ctx)
+ {
+ ctx->orphans_mutex.lock();
+ if (!ctx->orphaned_vertarray_ids.empty())
+ {
+ unsigned orphan_ct = (unsigned)ctx->orphaned_vertarray_ids.size();
+ glDeleteVertexArrays(orphan_ct, ctx->orphaned_vertarray_ids.data());
+ ctx->orphaned_vertarray_ids.clear();
+ }
+ ctx->orphans_mutex.unlock();
+ }
+
+Gwn_Context* GWN_context_create(void)
+ {
+#if TRUST_NO_ONE
+ assert(thread_is_main());
+#endif
+ Gwn_Context* ctx = (Gwn_Context*)calloc(1, sizeof(Gwn_Context));
+ glGenVertexArrays(1, &ctx->default_vao);
+ GWN_context_active_set(ctx);
+ return ctx;
+ }
+
+// to be called after GWN_context_active_set(ctx_to_destroy)
+void GWN_context_discard(Gwn_Context* ctx)
+ {
+#if TRUST_NO_ONE
+ // Make sure no other thread has locked it.
+ assert(ctx == active_ctx);
+ assert(ctx->thread == pthread_self());
+ assert(ctx->orphaned_vertarray_ids.empty());
+#endif
+ glDeleteVertexArrays(1, &ctx->default_vao);
+ free(ctx);
+ active_ctx = NULL;
+ }
+
+// ctx can be NULL
+void GWN_context_active_set(Gwn_Context* ctx)
+ {
+#if TRUST_NO_ONE
+ if (active_ctx)
+ active_ctx->thread = 0;
+ // Make sure no other context is already bound to this thread.
+ if (ctx)
+ {
+ // Make sure no other thread has locked it.
+ assert(ctx->thread == 0);
+ ctx->thread = pthread_self();
+ }
+#endif
+ if (ctx)
+ clear_orphans(ctx);
+ active_ctx = ctx;
+ }
+
+Gwn_Context* GWN_context_active_get(void)
+ {
+ return active_ctx;
+ }
+
+GLuint GWN_vao_default(void)
+ {
+#if TRUST_NO_ONE
+ assert(active_ctx); // need at least an active context
+ assert(active_ctx->thread == pthread_self()); // context has been activated by another thread!
+#endif
+ return active_ctx->default_vao;
+ }
+
+GLuint GWN_vao_alloc_new(void)
+ {
+#if TRUST_NO_ONE
+ assert(active_ctx); // need at least an active context
+ assert(active_ctx->thread == pthread_self()); // context has been activated by another thread!
+#endif
+ clear_orphans(active_ctx);
+
+ GLuint new_vao_id = 0;
+ glGenVertexArrays(1, &new_vao_id);
+ return new_vao_id;
+ }
+
+// this can be called from multiple thread
+void GWN_vao_free_new(GLuint vao_id, Gwn_Context* ctx)
+ {
+ if (ctx == active_ctx)
+ glDeleteVertexArrays(1, &vao_id);
+ else
+ {
+ ctx->orphans_mutex.lock();
+ ctx->orphaned_vertarray_ids.emplace_back(vao_id);
+ ctx->orphans_mutex.unlock();
+ }
+ }