mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 17:01:06 +02:00
Working on scene threading optimizations
This commit is contained in:
parent
f88a72894d
commit
e626ca3ccd
2 changed files with 137 additions and 39 deletions
|
@ -32,23 +32,23 @@ void Transaction::removeItem(ItemID id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transaction::addTransitionToItem(ItemID id, Transition::Type transition, ItemID boundId) {
|
void Transaction::addTransitionToItem(ItemID id, Transition::Type transition, ItemID boundId) {
|
||||||
_addedTransitions.emplace_back(TransitionAdd{ id, transition, boundId });
|
_addedTransitions.emplace_back(id, transition, boundId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transaction::removeTransitionFromItem(ItemID id) {
|
void Transaction::removeTransitionFromItem(ItemID id) {
|
||||||
_addedTransitions.emplace_back(TransitionAdd{ id, Transition::NONE, render::Item::INVALID_ITEM_ID });
|
_addedTransitions.emplace_back(id, Transition::NONE, render::Item::INVALID_ITEM_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transaction::reApplyTransitionToItem(ItemID id) {
|
void Transaction::reApplyTransitionToItem(ItemID id) {
|
||||||
_reAppliedTransitions.emplace_back(TransitionReApply{ id });
|
_reAppliedTransitions.emplace_back(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transaction::queryTransitionOnItem(ItemID id, TransitionQueryFunc func) {
|
void Transaction::queryTransitionOnItem(ItemID id, TransitionQueryFunc func) {
|
||||||
_queriedTransitions.emplace_back(TransitionQuery{ id, func });
|
_queriedTransitions.emplace_back(id, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transaction::updateItem(ItemID id, const UpdateFunctorPointer& functor) {
|
void Transaction::updateItem(ItemID id, const UpdateFunctorPointer& functor) {
|
||||||
_updatedItems.emplace_back(Update{ id, functor });
|
_updatedItems.emplace_back(id, functor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transaction::resetSelection(const Selection& selection) {
|
void Transaction::resetSelection(const Selection& selection) {
|
||||||
|
@ -56,28 +56,122 @@ void Transaction::resetSelection(const Selection& selection) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transaction::resetSelectionHighlight(const std::string& selectionName, const HighlightStyle& style) {
|
void Transaction::resetSelectionHighlight(const std::string& selectionName, const HighlightStyle& style) {
|
||||||
_highlightResets.emplace_back(HighlightReset{ selectionName, style });
|
_highlightResets.emplace_back(selectionName, style );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transaction::removeHighlightFromSelection(const std::string& selectionName) {
|
void Transaction::removeHighlightFromSelection(const std::string& selectionName) {
|
||||||
_highlightRemoves.emplace_back(selectionName);
|
_highlightRemoves.emplace_back(selectionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transaction::querySelectionHighlight(const std::string& selectionName, SelectionHighlightQueryFunc func) {
|
void Transaction::querySelectionHighlight(const std::string& selectionName, const SelectionHighlightQueryFunc& func) {
|
||||||
_highlightQueries.emplace_back(HighlightQuery{ selectionName, func });
|
_highlightQueries.emplace_back(selectionName, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transaction::reserve(const std::vector<Transaction>& transactionContainer) {
|
||||||
|
size_t resetItemsCount = 0;
|
||||||
|
size_t removedItemsCount = 0;
|
||||||
|
size_t updatedItemsCount = 0;
|
||||||
|
size_t resetSelectionsCount = 0;
|
||||||
|
size_t addedTransitionsCount = 0;
|
||||||
|
size_t queriedTransitionsCount = 0;
|
||||||
|
size_t reAppliedTransitionsCount = 0;
|
||||||
|
size_t highlightResetsCount = 0;
|
||||||
|
size_t highlightRemovesCount = 0;
|
||||||
|
size_t highlightQueriesCount = 0;
|
||||||
|
|
||||||
|
for (const auto& transaction : transactionContainer) {
|
||||||
|
resetItemsCount += transaction._resetItems.size();
|
||||||
|
removedItemsCount += transaction._removedItems.size();
|
||||||
|
updatedItemsCount += transaction._updatedItems.size();
|
||||||
|
resetSelectionsCount += transaction._resetSelections.size();
|
||||||
|
addedTransitionsCount += transaction._addedTransitions.size();
|
||||||
|
queriedTransitionsCount += transaction._queriedTransitions.size();
|
||||||
|
reAppliedTransitionsCount += transaction._reAppliedTransitions.size();
|
||||||
|
highlightResetsCount += transaction._highlightResets.size();
|
||||||
|
highlightRemovesCount += transaction._highlightRemoves.size();
|
||||||
|
highlightQueriesCount += transaction._highlightQueries.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
_resetItems.reserve(resetItemsCount);
|
||||||
|
_removedItems.reserve(removedItemsCount);
|
||||||
|
_updatedItems.reserve(updatedItemsCount);
|
||||||
|
_resetSelections.reserve(resetSelectionsCount);
|
||||||
|
_addedTransitions.reserve(addedTransitionsCount);
|
||||||
|
_queriedTransitions.reserve(queriedTransitionsCount);
|
||||||
|
_reAppliedTransitions.reserve(reAppliedTransitionsCount);
|
||||||
|
_highlightResets.reserve(highlightResetsCount);
|
||||||
|
_highlightRemoves.reserve(highlightRemovesCount);
|
||||||
|
_highlightQueries.reserve(highlightQueriesCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transaction::merge(const std::vector<Transaction>& transactionContainer) {
|
||||||
|
reserve(transactionContainer);
|
||||||
|
for (const auto& transaction : transactionContainer) {
|
||||||
|
merge(transaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Transaction::merge(std::vector<Transaction>&& transactionContainer) {
|
||||||
|
reserve(transactionContainer);
|
||||||
|
auto begin = std::make_move_iterator(transactionContainer.begin());
|
||||||
|
auto end = std::make_move_iterator(transactionContainer.end());
|
||||||
|
for (auto itr = begin; itr != end; ++itr) {
|
||||||
|
merge(*itr);
|
||||||
|
}
|
||||||
|
transactionContainer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void moveElements(T& target, T& source) {
|
||||||
|
target.insert(target.end(), std::make_move_iterator(source.begin()), std::make_move_iterator(source.begin()));
|
||||||
|
source.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void copyElements(T& target, const T& source) {
|
||||||
|
target.insert(target.end(), source.begin(), source.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Transaction::merge(Transaction&& transaction) {
|
||||||
|
moveElements(_resetItems, transaction._resetItems);
|
||||||
|
moveElements(_removedItems, transaction._removedItems);
|
||||||
|
moveElements(_updatedItems, transaction._updatedItems);
|
||||||
|
moveElements(_resetSelections, transaction._resetSelections);
|
||||||
|
moveElements(_addedTransitions, transaction._addedTransitions);
|
||||||
|
moveElements(_queriedTransitions, transaction._queriedTransitions);
|
||||||
|
moveElements(_reAppliedTransitions, transaction._reAppliedTransitions);
|
||||||
|
moveElements(_highlightResets, transaction._highlightResets);
|
||||||
|
moveElements(_highlightRemoves, transaction._highlightRemoves);
|
||||||
|
moveElements(_highlightQueries, transaction._highlightQueries);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transaction::merge(const Transaction& transaction) {
|
void Transaction::merge(const Transaction& transaction) {
|
||||||
_resetItems.insert(_resetItems.end(), transaction._resetItems.begin(), transaction._resetItems.end());
|
copyElements(_resetItems, transaction._resetItems);
|
||||||
_removedItems.insert(_removedItems.end(), transaction._removedItems.begin(), transaction._removedItems.end());
|
copyElements(_removedItems, transaction._removedItems);
|
||||||
_updatedItems.insert(_updatedItems.end(), transaction._updatedItems.begin(), transaction._updatedItems.end());
|
copyElements(_updatedItems, transaction._updatedItems);
|
||||||
_resetSelections.insert(_resetSelections.end(), transaction._resetSelections.begin(), transaction._resetSelections.end());
|
copyElements(_resetSelections, transaction._resetSelections);
|
||||||
_addedTransitions.insert(_addedTransitions.end(), transaction._addedTransitions.begin(), transaction._addedTransitions.end());
|
copyElements(_addedTransitions, transaction._addedTransitions);
|
||||||
_queriedTransitions.insert(_queriedTransitions.end(), transaction._queriedTransitions.begin(), transaction._queriedTransitions.end());
|
copyElements(_queriedTransitions, transaction._queriedTransitions);
|
||||||
_reAppliedTransitions.insert(_reAppliedTransitions.end(), transaction._reAppliedTransitions.begin(), transaction._reAppliedTransitions.end());
|
copyElements(_reAppliedTransitions, transaction._reAppliedTransitions);
|
||||||
_highlightResets.insert(_highlightResets.end(), transaction._highlightResets.begin(), transaction._highlightResets.end());
|
copyElements(_highlightResets, transaction._highlightResets);
|
||||||
_highlightRemoves.insert(_highlightRemoves.end(), transaction._highlightRemoves.begin(), transaction._highlightRemoves.end());
|
copyElements(_highlightRemoves, transaction._highlightRemoves);
|
||||||
_highlightQueries.insert(_highlightQueries.end(), transaction._highlightQueries.begin(), transaction._highlightQueries.end());
|
copyElements(_highlightQueries, transaction._highlightQueries);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transaction::clear() {
|
||||||
|
_resetItems.clear();
|
||||||
|
_removedItems.clear();
|
||||||
|
_updatedItems.clear();
|
||||||
|
_resetSelections.clear();
|
||||||
|
_addedTransitions.clear();
|
||||||
|
_queriedTransitions.clear();
|
||||||
|
_reAppliedTransitions.clear();
|
||||||
|
_highlightResets.clear();
|
||||||
|
_highlightRemoves.clear();
|
||||||
|
_highlightQueries.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,54 +196,50 @@ bool Scene::isAllocatedID(const ItemID& id) const {
|
||||||
|
|
||||||
/// Enqueue change batch to the scene
|
/// Enqueue change batch to the scene
|
||||||
void Scene::enqueueTransaction(const Transaction& transaction) {
|
void Scene::enqueueTransaction(const Transaction& transaction) {
|
||||||
_transactionQueueMutex.lock();
|
std::unique_lock<std::mutex> lock(_transactionQueueMutex);
|
||||||
_transactionQueue.push(transaction);
|
_transactionQueue.emplace_back(transaction);
|
||||||
_transactionQueueMutex.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void consolidateTransaction(TransactionQueue& queue, Transaction& singleBatch) {
|
void Scene::enqueueTransaction(Transaction&& transaction) {
|
||||||
while (!queue.empty()) {
|
std::unique_lock<std::mutex> lock(_transactionQueueMutex);
|
||||||
const auto& transaction = queue.front();
|
_transactionQueue.emplace_back(std::move(transaction));
|
||||||
singleBatch.merge(transaction);
|
|
||||||
queue.pop();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Scene::enqueueFrame() {
|
uint32_t Scene::enqueueFrame() {
|
||||||
PROFILE_RANGE(render, __FUNCTION__);
|
PROFILE_RANGE(render, __FUNCTION__);
|
||||||
Transaction consolidatedTransaction;
|
TransactionQueue localTransactionQueue;
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(_transactionQueueMutex);
|
std::unique_lock<std::mutex> lock(_transactionQueueMutex);
|
||||||
consolidateTransaction(_transactionQueue, consolidatedTransaction);
|
localTransactionQueue.swap(_transactionQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t frameNumber = 0;
|
Transaction consolidatedTransaction;
|
||||||
|
consolidatedTransaction.merge(std::move(localTransactionQueue));
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(_transactionFramesMutex);
|
std::unique_lock<std::mutex> lock(_transactionFramesMutex);
|
||||||
_transactionFrames.push_back(consolidatedTransaction);
|
_transactionFrames.push_back(consolidatedTransaction);
|
||||||
_transactionFrameNumber++;
|
|
||||||
frameNumber = _transactionFrameNumber;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return frameNumber;
|
return ++_transactionFrameNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Scene::processTransactionQueue() {
|
void Scene::processTransactionQueue() {
|
||||||
PROFILE_RANGE(render, __FUNCTION__);
|
PROFILE_RANGE(render, __FUNCTION__);
|
||||||
|
|
||||||
TransactionFrames queuedFrames;
|
static TransactionFrames queuedFrames;
|
||||||
{
|
{
|
||||||
// capture the queued frames and clear the queue
|
// capture the queued frames and clear the queue
|
||||||
std::unique_lock<std::mutex> lock(_transactionFramesMutex);
|
std::unique_lock<std::mutex> lock(_transactionFramesMutex);
|
||||||
queuedFrames = _transactionFrames;
|
queuedFrames.swap(_transactionFrames);
|
||||||
_transactionFrames.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// go through the queue of frames and process them
|
// go through the queue of frames and process them
|
||||||
for (auto& frame : queuedFrames) {
|
for (auto& frame : queuedFrames) {
|
||||||
processTransactionFrame(frame);
|
processTransactionFrame(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
queuedFrames.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::processTransactionFrame(const Transaction& transaction) {
|
void Scene::processTransactionFrame(const Transaction& transaction) {
|
||||||
|
|
|
@ -65,9 +65,14 @@ public:
|
||||||
|
|
||||||
void resetSelectionHighlight(const std::string& selectionName, const HighlightStyle& style = HighlightStyle());
|
void resetSelectionHighlight(const std::string& selectionName, const HighlightStyle& style = HighlightStyle());
|
||||||
void removeHighlightFromSelection(const std::string& selectionName);
|
void removeHighlightFromSelection(const std::string& selectionName);
|
||||||
void querySelectionHighlight(const std::string& selectionName, SelectionHighlightQueryFunc func);
|
void querySelectionHighlight(const std::string& selectionName, const SelectionHighlightQueryFunc& func);
|
||||||
|
|
||||||
|
void reserve(const std::vector<Transaction>& transactionContainer);
|
||||||
|
void merge(const std::vector<Transaction>& transactionContainer);
|
||||||
|
void merge(std::vector<Transaction>&& transactionContainer);
|
||||||
void merge(const Transaction& transaction);
|
void merge(const Transaction& transaction);
|
||||||
|
void merge(Transaction&& transaction);
|
||||||
|
void clear();
|
||||||
|
|
||||||
// Checkers if there is work to do when processing the transaction
|
// Checkers if there is work to do when processing the transaction
|
||||||
bool touchTransactions() const { return !_resetSelections.empty(); }
|
bool touchTransactions() const { return !_resetSelections.empty(); }
|
||||||
|
@ -107,7 +112,7 @@ protected:
|
||||||
HighlightRemoves _highlightRemoves;
|
HighlightRemoves _highlightRemoves;
|
||||||
HighlightQueries _highlightQueries;
|
HighlightQueries _highlightQueries;
|
||||||
};
|
};
|
||||||
typedef std::queue<Transaction> TransactionQueue;
|
typedef std::vector<Transaction> TransactionQueue;
|
||||||
|
|
||||||
|
|
||||||
// Scene is a container for Items
|
// Scene is a container for Items
|
||||||
|
@ -133,6 +138,9 @@ public:
|
||||||
// Enqueue transaction to the scene
|
// Enqueue transaction to the scene
|
||||||
void enqueueTransaction(const Transaction& transaction);
|
void enqueueTransaction(const Transaction& transaction);
|
||||||
|
|
||||||
|
// Enqueue transaction to the scene
|
||||||
|
void enqueueTransaction(Transaction&& transaction);
|
||||||
|
|
||||||
// Enqueue end of frame transactions boundary
|
// Enqueue end of frame transactions boundary
|
||||||
uint32_t enqueueFrame();
|
uint32_t enqueueFrame();
|
||||||
|
|
||||||
|
@ -187,7 +195,7 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
std::mutex _transactionFramesMutex;
|
std::mutex _transactionFramesMutex;
|
||||||
using TransactionFrames = std::list<Transaction>;
|
using TransactionFrames = std::vector<Transaction>;
|
||||||
TransactionFrames _transactionFrames;
|
TransactionFrames _transactionFrames;
|
||||||
uint32_t _transactionFrameNumber{ 0 };
|
uint32_t _transactionFrameNumber{ 0 };
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue