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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2015-11-22 07:15:56 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2015-11-23 00:49:43 +0300
commitd28431a6481a7698105ad45fc68a410e3cd71939 (patch)
treec3d25742b6bbd85c56fc23091ee3d726524384fe /intern/opennl
parent47ce2d7bef32a7f5de34ac3e0cfb8300a4e63cd9 (diff)
OpenNL: make the API thread safe by always passing context.
Previously two laplacian smooth or deform modifiers executing simultaneously could crash.
Diffstat (limited to 'intern/opennl')
-rw-r--r--intern/opennl/extern/ONL_opennl.h26
-rw-r--r--intern/opennl/intern/opennl.cpp162
2 files changed, 80 insertions, 108 deletions
diff --git a/intern/opennl/extern/ONL_opennl.h b/intern/opennl/extern/ONL_opennl.h
index 61a11fa8993..a414f40824b 100644
--- a/intern/opennl/extern/ONL_opennl.h
+++ b/intern/opennl/extern/ONL_opennl.h
@@ -77,35 +77,33 @@ typedef struct NLContext NLContext;
NLContext *nlNewContext(void);
void nlDeleteContext(NLContext *context);
-void nlMakeCurrent(NLContext *context);
-NLContext *nlGetCurrent(void);
/* State get/set */
-void nlSolverParameteri(NLenum pname, NLint param);
+void nlSolverParameteri(NLContext *context, NLenum pname, NLint param);
/* Variables */
-void nlSetVariable(NLuint rhsindex, NLuint index, NLdouble value);
-NLdouble nlGetVariable(NLuint rhsindex, NLuint index);
-void nlLockVariable(NLuint index);
-void nlUnlockVariable(NLuint index);
+void nlSetVariable(NLContext *context, NLuint rhsindex, NLuint index, NLdouble value);
+NLdouble nlGetVariable(NLContext *context, NLuint rhsindex, NLuint index);
+void nlLockVariable(NLContext *context, NLuint index);
+void nlUnlockVariable(NLContext *context, NLuint index);
/* Begin/End */
-void nlBegin(NLenum primitive);
-void nlEnd(NLenum primitive);
+void nlBegin(NLContext *context, NLenum primitive);
+void nlEnd(NLContext *context, NLenum primitive);
/* Setting elements in matrix/vector */
-void nlMatrixAdd(NLuint row, NLuint col, NLdouble value);
-void nlRightHandSideAdd(NLuint rhsindex, NLuint index, NLdouble value);
-void nlRightHandSideSet(NLuint rhsindex, NLuint index, NLdouble value);
+void nlMatrixAdd(NLContext *context, NLuint row, NLuint col, NLdouble value);
+void nlRightHandSideAdd(NLContext *context, NLuint rhsindex, NLuint index, NLdouble value);
+void nlRightHandSideSet(NLContext *context, NLuint rhsindex, NLuint index, NLdouble value);
/* Solve */
-void nlPrintMatrix(void);
-NLboolean nlSolve(NLboolean solveAgain);
+void nlPrintMatrix(NLContext *context);
+NLboolean nlSolve(NLContext *context, NLboolean solveAgain);
#ifdef __cplusplus
}
diff --git a/intern/opennl/intern/opennl.cpp b/intern/opennl/intern/opennl.cpp
index de128053342..076dce3b807 100644
--- a/intern/opennl/intern/opennl.cpp
+++ b/intern/opennl/intern/opennl.cpp
@@ -29,19 +29,20 @@
* levy@loria.fr
*
* ISA Project
- * LORIA, INRIA Lorraine,
+ * LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
- * 54506 VANDOEUVRE LES NANCY CEDEX
+ * 54506 VANDOEUVRE LES NANCY CEDEX
* FRANCE
*
* Note that the GNU General Public License does not permit incorporating
- * the Software into proprietary programs.
+ * the Software into proprietary programs.
*/
#include "ONL_opennl.h"
#include <Eigen/Sparse>
+#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <iostream>
@@ -100,22 +101,16 @@ struct NLContext {
NLboolean solve_again;
};
-static NLContext* __nlCurrentContext = NULL;
-
NLContext *nlNewContext(void)
{
NLContext* result = new NLContext();
result->state = NL_STATE_INITIAL;
result->nb_rhs = 1;
- nlMakeCurrent(result);
return result;
}
void nlDeleteContext(NLContext *context)
{
- if(__nlCurrentContext == context)
- __nlCurrentContext = NULL;
-
context->M.resize(0, 0);
context->MtM.resize(0, 0);
context->b.clear();
@@ -129,46 +124,36 @@ void nlDeleteContext(NLContext *context)
delete context;
}
-void nlMakeCurrent(NLContext *context)
-{
- __nlCurrentContext = context;
-}
-
-NLContext *nlGetCurrent(void)
-{
- return __nlCurrentContext;
-}
-
-static void __nlCheckState(NLenum state)
+static void __nlCheckState(NLContext *context, NLenum state)
{
- assert(__nlCurrentContext->state == state);
+ assert(context->state == state);
}
-static void __nlTransition(NLenum from_state, NLenum to_state)
+static void __nlTransition(NLContext *context, NLenum from_state, NLenum to_state)
{
- __nlCheckState(from_state);
- __nlCurrentContext->state = to_state;
+ __nlCheckState(context, from_state);
+ context->state = to_state;
}
/* Get/Set parameters */
-void nlSolverParameteri(NLenum pname, NLint param)
+void nlSolverParameteri(NLContext *context, NLenum pname, NLint param)
{
- __nlCheckState(NL_STATE_INITIAL);
+ __nlCheckState(context, NL_STATE_INITIAL);
switch(pname) {
case NL_NB_VARIABLES: {
assert(param > 0);
- __nlCurrentContext->nb_variables = (NLuint)param;
+ context->nb_variables = (NLuint)param;
} break;
case NL_NB_ROWS: {
assert(param > 0);
- __nlCurrentContext->nb_rows = (NLuint)param;
+ context->nb_rows = (NLuint)param;
} break;
case NL_LEAST_SQUARES: {
- __nlCurrentContext->least_squares = (NLboolean)param;
+ context->least_squares = (NLboolean)param;
} break;
case NL_NB_RIGHT_HAND_SIDES: {
- __nlCurrentContext->nb_rhs = (NLuint)param;
+ context->nb_rhs = (NLuint)param;
} break;
default: {
assert(0);
@@ -178,35 +163,34 @@ void nlSolverParameteri(NLenum pname, NLint param)
/* Get/Set Lock/Unlock variables */
-void nlSetVariable(NLuint rhsindex, NLuint index, NLdouble value)
+void nlSetVariable(NLContext *context, NLuint rhsindex, NLuint index, NLdouble value)
{
- __nlCheckState(NL_STATE_SYSTEM);
- __nlCurrentContext->variable[index].value[rhsindex] = value;
+ __nlCheckState(context, NL_STATE_SYSTEM);
+ context->variable[index].value[rhsindex] = value;
}
-NLdouble nlGetVariable(NLuint rhsindex, NLuint index)
+NLdouble nlGetVariable(NLContext *context, NLuint rhsindex, NLuint index)
{
- assert(__nlCurrentContext->state != NL_STATE_INITIAL);
- return __nlCurrentContext->variable[index].value[rhsindex];
+ assert(context->state != NL_STATE_INITIAL);
+ return context->variable[index].value[rhsindex];
}
-void nlLockVariable(NLuint index)
+void nlLockVariable(NLContext *context, NLuint index)
{
- __nlCheckState(NL_STATE_SYSTEM);
- __nlCurrentContext->variable[index].locked = true;
+ __nlCheckState(context, NL_STATE_SYSTEM);
+ context->variable[index].locked = true;
}
-void nlUnlockVariable(NLuint index)
+void nlUnlockVariable(NLContext *context, NLuint index)
{
- __nlCheckState(NL_STATE_SYSTEM);
- __nlCurrentContext->variable[index].locked = false;
+ __nlCheckState(context, NL_STATE_SYSTEM);
+ context->variable[index].locked = false;
}
/* System construction */
-static void __nlVariablesToVector()
+static void __nlVariablesToVector(NLContext *context)
{
- NLContext *context = __nlCurrentContext;
NLuint i, j, nb_rhs;
nb_rhs= context->nb_rhs;
@@ -220,9 +204,8 @@ static void __nlVariablesToVector()
}
}
-static void __nlVectorToVariables()
+static void __nlVectorToVariables(NLContext *context)
{
- NLContext *context = __nlCurrentContext;
NLuint i, j, nb_rhs;
nb_rhs= context->nb_rhs;
@@ -236,31 +219,30 @@ static void __nlVectorToVariables()
}
}
-static void __nlBeginSystem()
+static void __nlBeginSystem(NLContext *context)
{
- assert(__nlCurrentContext->nb_variables > 0);
+ assert(context->nb_variables > 0);
- if (__nlCurrentContext->solve_again)
- __nlTransition(NL_STATE_SYSTEM_SOLVED, NL_STATE_SYSTEM);
+ if (context->solve_again)
+ __nlTransition(context, NL_STATE_SYSTEM_SOLVED, NL_STATE_SYSTEM);
else {
- __nlTransition(NL_STATE_INITIAL, NL_STATE_SYSTEM);
+ __nlTransition(context, NL_STATE_INITIAL, NL_STATE_SYSTEM);
- __nlCurrentContext->variable.resize(__nlCurrentContext->nb_variables);
+ context->variable.resize(context->nb_variables);
}
}
-static void __nlEndSystem()
+static void __nlEndSystem(NLContext *context)
{
- __nlTransition(NL_STATE_MATRIX_CONSTRUCTED, NL_STATE_SYSTEM_CONSTRUCTED);
+ __nlTransition(context, NL_STATE_MATRIX_CONSTRUCTED, NL_STATE_SYSTEM_CONSTRUCTED);
}
-static void __nlBeginMatrix()
+static void __nlBeginMatrix(NLContext *context)
{
NLuint i;
NLuint m = 0, n = 0;
- NLContext *context = __nlCurrentContext;
- __nlTransition(NL_STATE_SYSTEM, NL_STATE_MATRIX);
+ __nlTransition(context, NL_STATE_SYSTEM, NL_STATE_MATRIX);
if (!context->solve_again) {
for(i=0; i<context->nb_variables; i++) {
@@ -275,6 +257,10 @@ static void __nlBeginMatrix()
context->m = m;
context->n = n;
+ /* reserve reasonable estimate */
+ context->Mtriplets.clear();
+ context->Mtriplets.reserve(std::max(m, n)*3);
+
context->b.resize(context->nb_rhs);
context->x.resize(context->nb_rhs);
@@ -289,18 +275,17 @@ static void __nlBeginMatrix()
context->b[i].setZero(context->m);
}
- __nlVariablesToVector();
+ __nlVariablesToVector(context);
}
-static void __nlEndMatrixRHS(NLuint rhs)
+static void __nlEndMatrixRHS(NLContext *context, NLuint rhs)
{
- NLContext *context = __nlCurrentContext;
NLVariable *variable;
NLuint i, j;
EigenVectorX& b = context->b[rhs];
- for(i=0; i<__nlCurrentContext->nb_variables; i++) {
+ for(i=0; i<context->nb_variables; i++) {
variable = &(context->variable[i]);
if(variable->locked) {
@@ -316,12 +301,10 @@ static void __nlEndMatrixRHS(NLuint rhs)
context->Mtb[rhs] = context->M.transpose() * b;
}
-static void __nlEndMatrix()
+static void __nlEndMatrix(NLContext *context)
{
- NLContext *context = __nlCurrentContext;
+ __nlTransition(context, NL_STATE_MATRIX, NL_STATE_MATRIX_CONSTRUCTED);
- __nlTransition(NL_STATE_MATRIX, NL_STATE_MATRIX_CONSTRUCTED);
-
if(!context->solve_again) {
context->M.resize(context->m, context->n);
context->M.setFromTriplets(context->Mtriplets.begin(), context->Mtriplets.end());
@@ -337,14 +320,12 @@ static void __nlEndMatrix()
}
for (NLuint rhs=0; rhs<context->nb_rhs; rhs++)
- __nlEndMatrixRHS(rhs);
+ __nlEndMatrixRHS(context, rhs);
}
-void nlMatrixAdd(NLuint row, NLuint col, NLdouble value)
+void nlMatrixAdd(NLContext *context, NLuint row, NLuint col, NLdouble value)
{
- NLContext *context = __nlCurrentContext;
-
- __nlCheckState(NL_STATE_MATRIX);
+ __nlCheckState(context, NL_STATE_MATRIX);
if(context->solve_again)
return;
@@ -368,11 +349,9 @@ void nlMatrixAdd(NLuint row, NLuint col, NLdouble value)
}
}
-void nlRightHandSideAdd(NLuint rhsindex, NLuint index, NLdouble value)
+void nlRightHandSideAdd(NLContext *context, NLuint rhsindex, NLuint index, NLdouble value)
{
- NLContext *context = __nlCurrentContext;
-
- __nlCheckState(NL_STATE_MATRIX);
+ __nlCheckState(context, NL_STATE_MATRIX);
if(context->least_squares) {
context->b[rhsindex][index] += value;
@@ -385,11 +364,9 @@ void nlRightHandSideAdd(NLuint rhsindex, NLuint index, NLdouble value)
}
}
-void nlRightHandSideSet(NLuint rhsindex, NLuint index, NLdouble value)
+void nlRightHandSideSet(NLContext *context, NLuint rhsindex, NLuint index, NLdouble value)
{
- NLContext *context = __nlCurrentContext;
-
- __nlCheckState(NL_STATE_MATRIX);
+ __nlCheckState(context, NL_STATE_MATRIX);
if(context->least_squares) {
context->b[rhsindex][index] = value;
@@ -402,14 +379,14 @@ void nlRightHandSideSet(NLuint rhsindex, NLuint index, NLdouble value)
}
}
-void nlBegin(NLenum prim)
+void nlBegin(NLContext *context, NLenum prim)
{
switch(prim) {
case NL_SYSTEM: {
- __nlBeginSystem();
+ __nlBeginSystem(context);
} break;
case NL_MATRIX: {
- __nlBeginMatrix();
+ __nlBeginMatrix(context);
} break;
default: {
assert(0);
@@ -417,14 +394,14 @@ void nlBegin(NLenum prim)
}
}
-void nlEnd(NLenum prim)
+void nlEnd(NLContext *context, NLenum prim)
{
switch(prim) {
case NL_SYSTEM: {
- __nlEndSystem();
+ __nlEndSystem(context);
} break;
case NL_MATRIX: {
- __nlEndMatrix();
+ __nlEndMatrix(context);
} break;
default: {
assert(0);
@@ -432,10 +409,8 @@ void nlEnd(NLenum prim)
}
}
-void nlPrintMatrix(void)
+void nlPrintMatrix(NLContext *context)
{
- NLContext *context = __nlCurrentContext;
-
std::cout << "A:" << context->M << std::endl;
for(NLuint rhs=0; rhs<context->nb_rhs; rhs++)
@@ -447,14 +422,13 @@ void nlPrintMatrix(void)
/* Solving */
-NLboolean nlSolve(NLboolean solveAgain)
+NLboolean nlSolve(NLContext *context, NLboolean solveAgain)
{
- NLContext *context = __nlCurrentContext;
NLboolean result = true;
- __nlCheckState(NL_STATE_SYSTEM_CONSTRUCTED);
+ __nlCheckState(context, NL_STATE_SYSTEM_CONSTRUCTED);
- if (!__nlCurrentContext->solve_again) {
+ if (!context->solve_again) {
EigenSparseMatrix& M = (context->least_squares)? context->MtM: context->M;
assert(M.rows() == M.cols());
@@ -486,12 +460,12 @@ NLboolean nlSolve(NLboolean solveAgain)
}
if (result) {
- __nlVectorToVariables();
+ __nlVectorToVariables(context);
if (solveAgain)
- __nlCurrentContext->solve_again = true;
+ context->solve_again = true;
- __nlTransition(NL_STATE_SYSTEM_CONSTRUCTED, NL_STATE_SYSTEM_SOLVED);
+ __nlTransition(context, NL_STATE_SYSTEM_CONSTRUCTED, NL_STATE_SYSTEM_SOLVED);
}
}