diff options
author | Jeroen Bakker <jeroen@blender.org> | 2021-03-19 15:52:45 +0300 |
---|---|---|
committer | Jeroen Bakker <jeroen@blender.org> | 2021-03-19 19:11:47 +0300 |
commit | 50c54354385a8b15e00b8f1538387ffc16773686 (patch) | |
tree | 787da698ef548a73e1c916f2063d7c089dbe975e | |
parent | 18b87e2e0b9393b9a20733b2396277a48a0b0c5d (diff) |
Cleanup: compositor - chunk order
No functional changes.
4 files changed, 103 insertions, 109 deletions
diff --git a/source/blender/compositor/intern/COM_ChunkOrder.cc b/source/blender/compositor/intern/COM_ChunkOrder.cc index 3baa50da487..9687154120d 100644 --- a/source/blender/compositor/intern/COM_ChunkOrder.cc +++ b/source/blender/compositor/intern/COM_ChunkOrder.cc @@ -17,22 +17,14 @@ */ #include "COM_ChunkOrder.h" -#include "BLI_math.h" -ChunkOrder::ChunkOrder() -{ - distance = 0.0; - number = 0; - x = 0; - y = 0; -} +#include "BLI_math.h" -void ChunkOrder::update_distance(ChunkOrderHotspot **hotspots, unsigned int len_hotspots) +void ChunkOrder::update_distance(ChunkOrderHotspot *hotspots, unsigned int len_hotspots) { - double new_distance = FLT_MAX; + double new_distance = DBL_MAX; for (int index = 0; index < len_hotspots; index++) { - ChunkOrderHotspot *hotspot = hotspots[index]; - double distance_to_hotspot = hotspot->calc_distance(x, y); + double distance_to_hotspot = hotspots[index].calc_distance(x, y); if (distance_to_hotspot < new_distance) { new_distance = distance_to_hotspot; } diff --git a/source/blender/compositor/intern/COM_ChunkOrder.h b/source/blender/compositor/intern/COM_ChunkOrder.h index 993622b346c..a634309f345 100644 --- a/source/blender/compositor/intern/COM_ChunkOrder.h +++ b/source/blender/compositor/intern/COM_ChunkOrder.h @@ -23,17 +23,17 @@ #endif #include "COM_ChunkOrderHotspot.h" -struct ChunkOrder { - unsigned int number; - int x; - int y; - double distance; - ChunkOrder(); +/** Helper to determine the order how chunks are prioritized during execution. */ +struct ChunkOrder { + unsigned int index = 0; + int x = 0; + int y = 0; + double distance = 0.0; friend bool operator<(const ChunkOrder &a, const ChunkOrder &b); - void update_distance(ChunkOrderHotspot **hotspots, unsigned int len_hotspots); + void update_distance(ChunkOrderHotspot *hotspots, unsigned int len_hotspots); #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("COM:ChunkOrderHotspot") diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cc b/source/blender/compositor/intern/COM_ExecutionGroup.cc index 86065c18993..c14287335fd 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cc +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cc @@ -34,10 +34,15 @@ #include "COM_defines.h" #include "BLI_math.h" +#include "BLI_rand.hh" #include "BLI_string.h" + #include "BLT_translation.h" + #include "MEM_guardedalloc.h" + #include "PIL_time.h" + #include "WM_api.h" #include "WM_types.h" @@ -178,136 +183,129 @@ void ExecutionGroup::determineNumberOfChunks() } } -/** - * this method is called for the top execution groups. containing the compositor node or the - * preview node or the viewer node) - */ -void ExecutionGroup::execute(ExecutionSystem *graph) +blender::Array<unsigned int> ExecutionGroup::determine_chunk_execution_order() const { - const CompositorContext &context = graph->getContext(); - const bNodeTree *bTree = context.getbNodeTree(); - if (this->m_width == 0 || this->m_height == 0) { - return; - } /** \note Break out... no pixels to calculate. */ - if (bTree->test_break && bTree->test_break(bTree->tbh)) { - return; - } /** \note Early break out for blur and preview nodes. */ - if (this->m_chunks_len == 0) { - return; - } /** \note Early break out. */ - unsigned int chunkNumber; - - this->m_executionStartTime = PIL_check_seconds_timer(); - - this->m_chunks_finished = 0; - this->m_bTree = bTree; - unsigned int index; - unsigned int *chunkOrder = (unsigned int *)MEM_mallocN(sizeof(unsigned int) * this->m_chunks_len, - __func__); - - for (chunkNumber = 0; chunkNumber < this->m_chunks_len; chunkNumber++) { - chunkOrder[chunkNumber] = chunkNumber; + int index; + blender::Array<unsigned int> chunk_order(m_chunks_len); + for (int chunk_index = 0; chunk_index < this->m_chunks_len; chunk_index++) { + chunk_order[chunk_index] = chunk_index; } + NodeOperation *operation = this->getOutputOperation(); - float centerX = 0.5; - float centerY = 0.5; - OrderOfChunks chunkorder = COM_ORDER_OF_CHUNKS_DEFAULT; + float centerX = 0.5f; + float centerY = 0.5f; + OrderOfChunks order_type = COM_ORDER_OF_CHUNKS_DEFAULT; if (operation->isViewerOperation()) { ViewerOperation *viewer = (ViewerOperation *)operation; centerX = viewer->getCenterX(); centerY = viewer->getCenterY(); - chunkorder = viewer->getChunkOrder(); + order_type = viewer->getChunkOrder(); } const int border_width = BLI_rcti_size_x(&this->m_viewerBorder); const int border_height = BLI_rcti_size_y(&this->m_viewerBorder); - switch (chunkorder) { - case COM_TO_RANDOM: - for (index = 0; index < 2 * this->m_chunks_len; index++) { - int index1 = rand() % this->m_chunks_len; - int index2 = rand() % this->m_chunks_len; - int s = chunkOrder[index1]; - chunkOrder[index1] = chunkOrder[index2]; - chunkOrder[index2] = s; - } + switch (order_type) { + case COM_TO_RANDOM: { + static blender::RandomNumberGenerator rng; + blender::MutableSpan<unsigned int> span = chunk_order.as_mutable_span(); + /* Shuffle twice to make it more random. */ + rng.shuffle(span); + rng.shuffle(span); break; + } case COM_TO_CENTER_OUT: { - ChunkOrderHotspot *hotspots[1]; - hotspots[0] = new ChunkOrderHotspot(border_width * centerX, border_height * centerY, 0.0f); - rcti rect; - ChunkOrder *chunkOrders = (ChunkOrder *)MEM_mallocN(sizeof(ChunkOrder) * this->m_chunks_len, - __func__); + ChunkOrderHotspot hotspot(border_width * centerX, border_height * centerY, 0.0f); + blender::Array<ChunkOrder> chunk_orders(m_chunks_len); for (index = 0; index < this->m_chunks_len; index++) { + rcti rect; determineChunkRect(&rect, index); - chunkOrders[index].number = index; - chunkOrders[index].x = rect.xmin - this->m_viewerBorder.xmin; - chunkOrders[index].y = rect.ymin - this->m_viewerBorder.ymin; - chunkOrders[index].update_distance(hotspots, 1); + chunk_orders[index].index = index; + chunk_orders[index].x = rect.xmin - this->m_viewerBorder.xmin; + chunk_orders[index].y = rect.ymin - this->m_viewerBorder.ymin; + chunk_orders[index].update_distance(&hotspot, 1); } - std::sort(&chunkOrders[0], &chunkOrders[this->m_chunks_len - 1]); + std::sort(&chunk_orders[0], &chunk_orders[this->m_chunks_len - 1]); for (index = 0; index < this->m_chunks_len; index++) { - chunkOrder[index] = chunkOrders[index].number; + chunk_order[index] = chunk_orders[index].index; } - delete hotspots[0]; - MEM_freeN(chunkOrders); break; } case COM_TO_RULE_OF_THIRDS: { - ChunkOrderHotspot *hotspots[9]; unsigned int tx = border_width / 6; unsigned int ty = border_height / 6; unsigned int mx = border_width / 2; unsigned int my = border_height / 2; unsigned int bx = mx + 2 * tx; unsigned int by = my + 2 * ty; - float addition = this->m_chunks_len / COM_RULE_OF_THIRDS_DIVIDER; - hotspots[0] = new ChunkOrderHotspot(mx, my, addition * 0); - hotspots[1] = new ChunkOrderHotspot(tx, my, addition * 1); - hotspots[2] = new ChunkOrderHotspot(bx, my, addition * 2); - hotspots[3] = new ChunkOrderHotspot(bx, by, addition * 3); - hotspots[4] = new ChunkOrderHotspot(tx, ty, addition * 4); - hotspots[5] = new ChunkOrderHotspot(bx, ty, addition * 5); - hotspots[6] = new ChunkOrderHotspot(tx, by, addition * 6); - hotspots[7] = new ChunkOrderHotspot(mx, ty, addition * 7); - hotspots[8] = new ChunkOrderHotspot(mx, by, addition * 8); - rcti rect; - ChunkOrder *chunkOrders = (ChunkOrder *)MEM_mallocN(sizeof(ChunkOrder) * this->m_chunks_len, - __func__); + + ChunkOrderHotspot hotspots[9]{ + ChunkOrderHotspot(mx, my, addition * 0), + ChunkOrderHotspot(tx, my, addition * 1), + ChunkOrderHotspot(bx, my, addition * 2), + ChunkOrderHotspot(bx, by, addition * 3), + ChunkOrderHotspot(tx, ty, addition * 4), + ChunkOrderHotspot(bx, ty, addition * 5), + ChunkOrderHotspot(tx, by, addition * 6), + ChunkOrderHotspot(mx, ty, addition * 7), + ChunkOrderHotspot(mx, by, addition * 8), + }; + + blender::Array<ChunkOrder> chunk_orders(m_chunks_len); for (index = 0; index < this->m_chunks_len; index++) { + rcti rect; determineChunkRect(&rect, index); - chunkOrders[index].number = index; - chunkOrders[index].x = rect.xmin - this->m_viewerBorder.xmin; - chunkOrders[index].y = rect.ymin - this->m_viewerBorder.ymin; - chunkOrders[index].update_distance(hotspots, 9); + chunk_orders[index].index = index; + chunk_orders[index].x = rect.xmin - this->m_viewerBorder.xmin; + chunk_orders[index].y = rect.ymin - this->m_viewerBorder.ymin; + chunk_orders[index].update_distance(hotspots, 9); } - std::sort(&chunkOrders[0], &chunkOrders[this->m_chunks_len]); + std::sort(&chunk_orders[0], &chunk_orders[this->m_chunks_len]); for (index = 0; index < this->m_chunks_len; index++) { - chunkOrder[index] = chunkOrders[index].number; + chunk_order[index] = chunk_orders[index].index; } - delete hotspots[0]; - delete hotspots[1]; - delete hotspots[2]; - delete hotspots[3]; - delete hotspots[4]; - delete hotspots[5]; - delete hotspots[6]; - delete hotspots[7]; - delete hotspots[8]; - MEM_freeN(chunkOrders); break; } case COM_TO_TOP_DOWN: default: break; } + return chunk_order; +} + +/** + * this method is called for the top execution groups. containing the compositor node or the + * preview node or the viewer node) + */ +void ExecutionGroup::execute(ExecutionSystem *graph) +{ + const CompositorContext &context = graph->getContext(); + const bNodeTree *bTree = context.getbNodeTree(); + if (this->m_width == 0 || this->m_height == 0) { + return; + } /** \note Break out... no pixels to calculate. */ + if (bTree->test_break && bTree->test_break(bTree->tbh)) { + return; + } /** \note Early break out for blur and preview nodes. */ + if (this->m_chunks_len == 0) { + return; + } /** \note Early break out. */ + unsigned int chunk_index; + + this->m_executionStartTime = PIL_check_seconds_timer(); + + this->m_chunks_finished = 0; + this->m_bTree = bTree; + unsigned int index; + + blender::Array<unsigned int> chunk_order = determine_chunk_execution_order(); DebugInfo::execution_group_started(this); DebugInfo::graphviz(graph); @@ -324,10 +322,10 @@ void ExecutionGroup::execute(ExecutionSystem *graph) for (index = startIndex; index < this->m_chunks_len && numberEvaluated < maxNumberEvaluated; index++) { - chunkNumber = chunkOrder[index]; - int yChunk = chunkNumber / this->m_x_chunks_len; - int xChunk = chunkNumber - (yChunk * this->m_x_chunks_len); - switch (m_chunk_execution_states[chunkNumber]) { + chunk_index = chunk_order[index]; + int yChunk = chunk_index / this->m_x_chunks_len; + int xChunk = chunk_index - (yChunk * this->m_x_chunks_len); + switch (m_chunk_execution_states[chunk_index]) { case eChunkExecutionState::NOT_SCHEDULED: { scheduleChunkWhenPossible(graph, xChunk, yChunk); finished = false; @@ -361,8 +359,6 @@ void ExecutionGroup::execute(ExecutionSystem *graph) } DebugInfo::execution_group_finished(this); DebugInfo::graphviz(graph); - - MEM_freeN(chunkOrder); } MemoryBuffer **ExecutionGroup::getInputBuffersOpenCL(int chunkNumber) diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index d59442db246..565c1538f1f 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -22,6 +22,7 @@ # include "MEM_guardedalloc.h" #endif +#include "BLI_array.hh" #include "BLI_rect.h" #include "BLI_vector.hh" @@ -248,6 +249,11 @@ class ExecutionGroup { ReadBufferOperation *readOperation, rcti *output); + /** + * Return the execution order of the user visible chunks. + */ + blender::Array<unsigned int> determine_chunk_execution_order() const; + public: // constructors ExecutionGroup(); |