diff --git a/xatlas.cpp b/xatlas.cpp index e9e2fd3..f480674 100644 --- a/xatlas.cpp +++ b/xatlas.cpp @@ -3235,6 +3235,8 @@ class sync_unordered_map { } }; +const uint64_t defaultConcurrency = std::thread::hardware_concurrency() <= 1 ? 1 : std::thread::hardware_concurrency() - 1; + #if XA_MULTITHREADED class TaskScheduler { @@ -3257,12 +3259,11 @@ class TaskScheduler TaskGroup(const TaskGroup&) = default; }; - public: - TaskScheduler() : m_shutdown(false) + TaskScheduler(uint64_t threadPoolSize = defaultConcurrency) : m_shutdown(false) { m_threadIndex = 0; - m_workers.resize(std::thread::hardware_concurrency() <= 1 ? 1 : std::thread::hardware_concurrency() - 1); + m_workers.resize(threadPoolSize); for (uint64_t i = 0; i < m_workers.size(); i++) { new (&m_workers[i]) Worker(); m_workers[i].wakeup = false; @@ -8965,11 +8966,11 @@ struct Context bool uvMeshChartsComputed = false; }; -Atlas *Create() +Atlas *Create(uint64_t concurrency) { Context *ctx = XA_NEW(internal::MemTag::Default, Context); memset(&ctx->atlas, 0, sizeof(Atlas)); - ctx->taskScheduler = XA_NEW(internal::MemTag::Default, internal::TaskScheduler); + ctx->taskScheduler = XA_NEW_ARGS(internal::MemTag::Default, internal::TaskScheduler, concurrency); return &ctx->atlas; } diff --git a/xatlas.h b/xatlas.h index 9c46391..1320c70 100644 --- a/xatlas.h +++ b/xatlas.h @@ -96,8 +96,12 @@ struct Atlas float texelsPerUnit; // Equal to PackOptions texelsPerUnit if texelsPerUnit > 0, otherwise an estimated value to match PackOptions resolution. }; +namespace internal { +extern const uint64_t defaultConcurrency; +} + // Create an empty atlas. -Atlas *Create(); +Atlas *Create(uint64_t concurrency = internal::defaultConcurrency); void Destroy(Atlas *atlas); @@ -117,7 +121,7 @@ struct MeshDecl const void *vertexNormalData = nullptr; // optional const void *vertexUvData = nullptr; // optional. The input UVs are provided as a hint to the chart generator. const void *indexData = nullptr; // optional - + // Optional. Must be indexCount / 3 in length. // Don't atlas faces set to true. Ignored faces still exist in the output meshes, Vertex uv is set to (0, 0) and Vertex atlasIndex to -1. const bool *faceIgnoreData = nullptr;