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 'source/blender/compositor/intern/COM_ExecutionGroup.cpp')
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.cpp964
1 files changed, 503 insertions, 461 deletions
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
index f636a211ff6..50caf51cf48 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
@@ -43,135 +43,147 @@
ExecutionGroup::ExecutionGroup()
{
- this->m_isOutput = false;
- this->m_complex = false;
- this->m_chunkExecutionStates = NULL;
- this->m_bTree = NULL;
- this->m_height = 0;
- this->m_width = 0;
- this->m_cachedMaxReadBufferOffset = 0;
- this->m_numberOfXChunks = 0;
- this->m_numberOfYChunks = 0;
- this->m_numberOfChunks = 0;
- this->m_initialized = false;
- this->m_openCL = false;
- this->m_singleThreaded = false;
- this->m_chunksFinished = 0;
- BLI_rcti_init(&this->m_viewerBorder, 0, 0, 0, 0);
- this->m_executionStartTime = 0;
+ this->m_isOutput = false;
+ this->m_complex = false;
+ this->m_chunkExecutionStates = NULL;
+ this->m_bTree = NULL;
+ this->m_height = 0;
+ this->m_width = 0;
+ this->m_cachedMaxReadBufferOffset = 0;
+ this->m_numberOfXChunks = 0;
+ this->m_numberOfYChunks = 0;
+ this->m_numberOfChunks = 0;
+ this->m_initialized = false;
+ this->m_openCL = false;
+ this->m_singleThreaded = false;
+ this->m_chunksFinished = 0;
+ BLI_rcti_init(&this->m_viewerBorder, 0, 0, 0, 0);
+ this->m_executionStartTime = 0;
}
CompositorPriority ExecutionGroup::getRenderPriotrity()
{
- return this->getOutputOperation()->getRenderPriority();
+ return this->getOutputOperation()->getRenderPriority();
}
bool ExecutionGroup::canContainOperation(NodeOperation *operation)
{
- if (!this->m_initialized) { return true; }
-
- if (operation->isReadBufferOperation()) { return true; }
- if (operation->isWriteBufferOperation()) { return false; }
- if (operation->isSetOperation()) { return true; }
-
- /* complex groups don't allow further ops (except read buffer and values, see above) */
- if (m_complex) { return false; }
- /* complex ops can't be added to other groups (except their own, which they initialize, see above) */
- if (operation->isComplex()) { return false; }
-
- return true;
+ if (!this->m_initialized) {
+ return true;
+ }
+
+ if (operation->isReadBufferOperation()) {
+ return true;
+ }
+ if (operation->isWriteBufferOperation()) {
+ return false;
+ }
+ if (operation->isSetOperation()) {
+ return true;
+ }
+
+ /* complex groups don't allow further ops (except read buffer and values, see above) */
+ if (m_complex) {
+ return false;
+ }
+ /* complex ops can't be added to other groups (except their own, which they initialize, see above) */
+ if (operation->isComplex()) {
+ return false;
+ }
+
+ return true;
}
bool ExecutionGroup::addOperation(NodeOperation *operation)
{
- if (!canContainOperation(operation))
- return false;
+ if (!canContainOperation(operation))
+ return false;
- if (!operation->isReadBufferOperation() && !operation->isWriteBufferOperation()) {
- m_complex = operation->isComplex();
- m_openCL = operation->isOpenCL();
- m_singleThreaded = operation->isSingleThreaded();
- m_initialized = true;
- }
+ if (!operation->isReadBufferOperation() && !operation->isWriteBufferOperation()) {
+ m_complex = operation->isComplex();
+ m_openCL = operation->isOpenCL();
+ m_singleThreaded = operation->isSingleThreaded();
+ m_initialized = true;
+ }
- m_operations.push_back(operation);
+ m_operations.push_back(operation);
- return true;
+ return true;
}
NodeOperation *ExecutionGroup::getOutputOperation() const
{
- return this->m_operations[0]; // the first operation of the group is always the output operation.
+ return this
+ ->m_operations[0]; // the first operation of the group is always the output operation.
}
void ExecutionGroup::initExecution()
{
- if (this->m_chunkExecutionStates != NULL) {
- MEM_freeN(this->m_chunkExecutionStates);
- }
- unsigned int index;
- determineNumberOfChunks();
-
- this->m_chunkExecutionStates = NULL;
- if (this->m_numberOfChunks != 0) {
- this->m_chunkExecutionStates = (ChunkExecutionState *)MEM_mallocN(sizeof(ChunkExecutionState) * this->m_numberOfChunks, __func__);
- for (index = 0; index < this->m_numberOfChunks; index++) {
- this->m_chunkExecutionStates[index] = COM_ES_NOT_SCHEDULED;
- }
- }
-
-
- unsigned int maxNumber = 0;
-
- for (index = 0; index < this->m_operations.size(); index++) {
- NodeOperation *operation = this->m_operations[index];
- if (operation->isReadBufferOperation()) {
- ReadBufferOperation *readOperation = (ReadBufferOperation *)operation;
- this->m_cachedReadOperations.push_back(readOperation);
- maxNumber = max(maxNumber, readOperation->getOffset());
- }
- }
- maxNumber++;
- this->m_cachedMaxReadBufferOffset = maxNumber;
-
+ if (this->m_chunkExecutionStates != NULL) {
+ MEM_freeN(this->m_chunkExecutionStates);
+ }
+ unsigned int index;
+ determineNumberOfChunks();
+
+ this->m_chunkExecutionStates = NULL;
+ if (this->m_numberOfChunks != 0) {
+ this->m_chunkExecutionStates = (ChunkExecutionState *)MEM_mallocN(
+ sizeof(ChunkExecutionState) * this->m_numberOfChunks, __func__);
+ for (index = 0; index < this->m_numberOfChunks; index++) {
+ this->m_chunkExecutionStates[index] = COM_ES_NOT_SCHEDULED;
+ }
+ }
+
+ unsigned int maxNumber = 0;
+
+ for (index = 0; index < this->m_operations.size(); index++) {
+ NodeOperation *operation = this->m_operations[index];
+ if (operation->isReadBufferOperation()) {
+ ReadBufferOperation *readOperation = (ReadBufferOperation *)operation;
+ this->m_cachedReadOperations.push_back(readOperation);
+ maxNumber = max(maxNumber, readOperation->getOffset());
+ }
+ }
+ maxNumber++;
+ this->m_cachedMaxReadBufferOffset = maxNumber;
}
void ExecutionGroup::deinitExecution()
{
- if (this->m_chunkExecutionStates != NULL) {
- MEM_freeN(this->m_chunkExecutionStates);
- this->m_chunkExecutionStates = NULL;
- }
- this->m_numberOfChunks = 0;
- this->m_numberOfXChunks = 0;
- this->m_numberOfYChunks = 0;
- this->m_cachedReadOperations.clear();
- this->m_bTree = NULL;
+ if (this->m_chunkExecutionStates != NULL) {
+ MEM_freeN(this->m_chunkExecutionStates);
+ this->m_chunkExecutionStates = NULL;
+ }
+ this->m_numberOfChunks = 0;
+ this->m_numberOfXChunks = 0;
+ this->m_numberOfYChunks = 0;
+ this->m_cachedReadOperations.clear();
+ this->m_bTree = NULL;
}
void ExecutionGroup::determineResolution(unsigned int resolution[2])
{
- NodeOperation *operation = this->getOutputOperation();
- resolution[0] = operation->getWidth();
- resolution[1] = operation->getHeight();
- this->setResolution(resolution);
- BLI_rcti_init(&this->m_viewerBorder, 0, this->m_width, 0, this->m_height);
+ NodeOperation *operation = this->getOutputOperation();
+ resolution[0] = operation->getWidth();
+ resolution[1] = operation->getHeight();
+ this->setResolution(resolution);
+ BLI_rcti_init(&this->m_viewerBorder, 0, this->m_width, 0, this->m_height);
}
void ExecutionGroup::determineNumberOfChunks()
{
- if (this->m_singleThreaded) {
- this->m_numberOfXChunks = 1;
- this->m_numberOfYChunks = 1;
- this->m_numberOfChunks = 1;
- }
- else {
- const float chunkSizef = this->m_chunkSize;
- const int border_width = BLI_rcti_size_x(&this->m_viewerBorder);
- const int border_height = BLI_rcti_size_y(&this->m_viewerBorder);
- this->m_numberOfXChunks = ceil(border_width / chunkSizef);
- this->m_numberOfYChunks = ceil(border_height / chunkSizef);
- this->m_numberOfChunks = this->m_numberOfXChunks * this->m_numberOfYChunks;
- }
+ if (this->m_singleThreaded) {
+ this->m_numberOfXChunks = 1;
+ this->m_numberOfYChunks = 1;
+ this->m_numberOfChunks = 1;
+ }
+ else {
+ const float chunkSizef = this->m_chunkSize;
+ const int border_width = BLI_rcti_size_x(&this->m_viewerBorder);
+ const int border_height = BLI_rcti_size_y(&this->m_viewerBorder);
+ this->m_numberOfXChunks = ceil(border_width / chunkSizef);
+ this->m_numberOfYChunks = ceil(border_height / chunkSizef);
+ this->m_numberOfChunks = this->m_numberOfXChunks * this->m_numberOfYChunks;
+ }
}
/**
@@ -179,422 +191,452 @@ void ExecutionGroup::determineNumberOfChunks()
*/
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_numberOfChunks == 0) {return; } /// \note: early break out
- unsigned int chunkNumber;
-
- this->m_executionStartTime = PIL_check_seconds_timer();
-
- this->m_chunksFinished = 0;
- this->m_bTree = bTree;
- unsigned int index;
- unsigned int *chunkOrder = (unsigned int *)MEM_mallocN(sizeof(unsigned int) * this->m_numberOfChunks, __func__);
-
- for (chunkNumber = 0; chunkNumber < this->m_numberOfChunks; chunkNumber++) {
- chunkOrder[chunkNumber] = chunkNumber;
- }
- NodeOperation *operation = this->getOutputOperation();
- float centerX = 0.5;
- float centerY = 0.5;
- OrderOfChunks chunkorder = COM_ORDER_OF_CHUNKS_DEFAULT;
-
- if (operation->isViewerOperation()) {
- ViewerOperation *viewer = (ViewerOperation *)operation;
- centerX = viewer->getCenterX();
- centerY = viewer->getCenterY();
- chunkorder = 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_numberOfChunks; index++) {
- int index1 = rand() % this->m_numberOfChunks;
- int index2 = rand() % this->m_numberOfChunks;
- int s = chunkOrder[index1];
- chunkOrder[index1] = chunkOrder[index2];
- chunkOrder[index2] = s;
- }
- 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_numberOfChunks, __func__);
- for (index = 0; index < this->m_numberOfChunks; index++) {
- determineChunkRect(&rect, index);
- chunkOrders[index].setChunkNumber(index);
- chunkOrders[index].setX(rect.xmin - this->m_viewerBorder.xmin);
- chunkOrders[index].setY(rect.ymin - this->m_viewerBorder.ymin);
- chunkOrders[index].determineDistance(hotspots, 1);
- }
-
- std::sort(&chunkOrders[0], &chunkOrders[this->m_numberOfChunks - 1]);
- for (index = 0; index < this->m_numberOfChunks; index++) {
- chunkOrder[index] = chunkOrders[index].getChunkNumber();
- }
-
- 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_numberOfChunks / 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_numberOfChunks, __func__);
- for (index = 0; index < this->m_numberOfChunks; index++) {
- determineChunkRect(&rect, index);
- chunkOrders[index].setChunkNumber(index);
- chunkOrders[index].setX(rect.xmin - this->m_viewerBorder.xmin);
- chunkOrders[index].setY(rect.ymin - this->m_viewerBorder.ymin);
- chunkOrders[index].determineDistance(hotspots, 9);
- }
-
- std::sort(&chunkOrders[0], &chunkOrders[this->m_numberOfChunks]);
-
- for (index = 0; index < this->m_numberOfChunks; index++) {
- chunkOrder[index] = chunkOrders[index].getChunkNumber();
- }
-
- 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;
- }
-
- DebugInfo::execution_group_started(this);
- DebugInfo::graphviz(graph);
-
- bool breaked = false;
- bool finished = false;
- unsigned int startIndex = 0;
- const int maxNumberEvaluated = BLI_system_thread_count() * 2;
-
- while (!finished && !breaked) {
- bool startEvaluated = false;
- finished = true;
- int numberEvaluated = 0;
-
- for (index = startIndex; index < this->m_numberOfChunks && numberEvaluated < maxNumberEvaluated; index++) {
- chunkNumber = chunkOrder[index];
- int yChunk = chunkNumber / this->m_numberOfXChunks;
- int xChunk = chunkNumber - (yChunk * this->m_numberOfXChunks);
- const ChunkExecutionState state = this->m_chunkExecutionStates[chunkNumber];
- if (state == COM_ES_NOT_SCHEDULED) {
- scheduleChunkWhenPossible(graph, xChunk, yChunk);
- finished = false;
- startEvaluated = true;
- numberEvaluated++;
-
- if (bTree->update_draw)
- bTree->update_draw(bTree->udh);
- }
- else if (state == COM_ES_SCHEDULED) {
- finished = false;
- startEvaluated = true;
- numberEvaluated++;
- }
- else if (state == COM_ES_EXECUTED && !startEvaluated) {
- startIndex = index + 1;
- }
- }
-
- WorkScheduler::finish();
-
- if (bTree->test_break && bTree->test_break(bTree->tbh)) {
- breaked = true;
- }
- }
- DebugInfo::execution_group_finished(this);
- DebugInfo::graphviz(graph);
-
- MEM_freeN(chunkOrder);
+ 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_numberOfChunks == 0) {
+ return;
+ } /// \note: early break out
+ unsigned int chunkNumber;
+
+ this->m_executionStartTime = PIL_check_seconds_timer();
+
+ this->m_chunksFinished = 0;
+ this->m_bTree = bTree;
+ unsigned int index;
+ unsigned int *chunkOrder = (unsigned int *)MEM_mallocN(
+ sizeof(unsigned int) * this->m_numberOfChunks, __func__);
+
+ for (chunkNumber = 0; chunkNumber < this->m_numberOfChunks; chunkNumber++) {
+ chunkOrder[chunkNumber] = chunkNumber;
+ }
+ NodeOperation *operation = this->getOutputOperation();
+ float centerX = 0.5;
+ float centerY = 0.5;
+ OrderOfChunks chunkorder = COM_ORDER_OF_CHUNKS_DEFAULT;
+
+ if (operation->isViewerOperation()) {
+ ViewerOperation *viewer = (ViewerOperation *)operation;
+ centerX = viewer->getCenterX();
+ centerY = viewer->getCenterY();
+ chunkorder = 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_numberOfChunks; index++) {
+ int index1 = rand() % this->m_numberOfChunks;
+ int index2 = rand() % this->m_numberOfChunks;
+ int s = chunkOrder[index1];
+ chunkOrder[index1] = chunkOrder[index2];
+ chunkOrder[index2] = s;
+ }
+ 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_numberOfChunks, __func__);
+ for (index = 0; index < this->m_numberOfChunks; index++) {
+ determineChunkRect(&rect, index);
+ chunkOrders[index].setChunkNumber(index);
+ chunkOrders[index].setX(rect.xmin - this->m_viewerBorder.xmin);
+ chunkOrders[index].setY(rect.ymin - this->m_viewerBorder.ymin);
+ chunkOrders[index].determineDistance(hotspots, 1);
+ }
+
+ std::sort(&chunkOrders[0], &chunkOrders[this->m_numberOfChunks - 1]);
+ for (index = 0; index < this->m_numberOfChunks; index++) {
+ chunkOrder[index] = chunkOrders[index].getChunkNumber();
+ }
+
+ 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_numberOfChunks / 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_numberOfChunks, __func__);
+ for (index = 0; index < this->m_numberOfChunks; index++) {
+ determineChunkRect(&rect, index);
+ chunkOrders[index].setChunkNumber(index);
+ chunkOrders[index].setX(rect.xmin - this->m_viewerBorder.xmin);
+ chunkOrders[index].setY(rect.ymin - this->m_viewerBorder.ymin);
+ chunkOrders[index].determineDistance(hotspots, 9);
+ }
+
+ std::sort(&chunkOrders[0], &chunkOrders[this->m_numberOfChunks]);
+
+ for (index = 0; index < this->m_numberOfChunks; index++) {
+ chunkOrder[index] = chunkOrders[index].getChunkNumber();
+ }
+
+ 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;
+ }
+
+ DebugInfo::execution_group_started(this);
+ DebugInfo::graphviz(graph);
+
+ bool breaked = false;
+ bool finished = false;
+ unsigned int startIndex = 0;
+ const int maxNumberEvaluated = BLI_system_thread_count() * 2;
+
+ while (!finished && !breaked) {
+ bool startEvaluated = false;
+ finished = true;
+ int numberEvaluated = 0;
+
+ for (index = startIndex;
+ index < this->m_numberOfChunks && numberEvaluated < maxNumberEvaluated;
+ index++) {
+ chunkNumber = chunkOrder[index];
+ int yChunk = chunkNumber / this->m_numberOfXChunks;
+ int xChunk = chunkNumber - (yChunk * this->m_numberOfXChunks);
+ const ChunkExecutionState state = this->m_chunkExecutionStates[chunkNumber];
+ if (state == COM_ES_NOT_SCHEDULED) {
+ scheduleChunkWhenPossible(graph, xChunk, yChunk);
+ finished = false;
+ startEvaluated = true;
+ numberEvaluated++;
+
+ if (bTree->update_draw)
+ bTree->update_draw(bTree->udh);
+ }
+ else if (state == COM_ES_SCHEDULED) {
+ finished = false;
+ startEvaluated = true;
+ numberEvaluated++;
+ }
+ else if (state == COM_ES_EXECUTED && !startEvaluated) {
+ startIndex = index + 1;
+ }
+ }
+
+ WorkScheduler::finish();
+
+ if (bTree->test_break && bTree->test_break(bTree->tbh)) {
+ breaked = true;
+ }
+ }
+ DebugInfo::execution_group_finished(this);
+ DebugInfo::graphviz(graph);
+
+ MEM_freeN(chunkOrder);
}
MemoryBuffer **ExecutionGroup::getInputBuffersOpenCL(int chunkNumber)
{
- rcti rect;
- vector<MemoryProxy *> memoryproxies;
- unsigned int index;
- determineChunkRect(&rect, chunkNumber);
-
- this->determineDependingMemoryProxies(&memoryproxies);
- MemoryBuffer **memoryBuffers = (MemoryBuffer **)MEM_callocN(sizeof(MemoryBuffer *) * this->m_cachedMaxReadBufferOffset, __func__);
- rcti output;
- for (index = 0; index < this->m_cachedReadOperations.size(); index++) {
- ReadBufferOperation *readOperation = (ReadBufferOperation *)this->m_cachedReadOperations[index];
- MemoryProxy *memoryProxy = readOperation->getMemoryProxy();
- this->determineDependingAreaOfInterest(&rect, readOperation, &output);
- MemoryBuffer *memoryBuffer = memoryProxy->getExecutor()->constructConsolidatedMemoryBuffer(memoryProxy, &output);
- memoryBuffers[readOperation->getOffset()] = memoryBuffer;
- }
- return memoryBuffers;
+ rcti rect;
+ vector<MemoryProxy *> memoryproxies;
+ unsigned int index;
+ determineChunkRect(&rect, chunkNumber);
+
+ this->determineDependingMemoryProxies(&memoryproxies);
+ MemoryBuffer **memoryBuffers = (MemoryBuffer **)MEM_callocN(
+ sizeof(MemoryBuffer *) * this->m_cachedMaxReadBufferOffset, __func__);
+ rcti output;
+ for (index = 0; index < this->m_cachedReadOperations.size(); index++) {
+ ReadBufferOperation *readOperation =
+ (ReadBufferOperation *)this->m_cachedReadOperations[index];
+ MemoryProxy *memoryProxy = readOperation->getMemoryProxy();
+ this->determineDependingAreaOfInterest(&rect, readOperation, &output);
+ MemoryBuffer *memoryBuffer = memoryProxy->getExecutor()->constructConsolidatedMemoryBuffer(
+ memoryProxy, &output);
+ memoryBuffers[readOperation->getOffset()] = memoryBuffer;
+ }
+ return memoryBuffers;
}
-MemoryBuffer *ExecutionGroup::constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy, rcti *rect)
+MemoryBuffer *ExecutionGroup::constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy,
+ rcti *rect)
{
- MemoryBuffer *imageBuffer = memoryProxy->getBuffer();
- MemoryBuffer *result = new MemoryBuffer(memoryProxy, rect);
- result->copyContentFrom(imageBuffer);
- return result;
+ MemoryBuffer *imageBuffer = memoryProxy->getBuffer();
+ MemoryBuffer *result = new MemoryBuffer(memoryProxy, rect);
+ result->copyContentFrom(imageBuffer);
+ return result;
}
void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer **memoryBuffers)
{
- if (this->m_chunkExecutionStates[chunkNumber] == COM_ES_SCHEDULED)
- this->m_chunkExecutionStates[chunkNumber] = COM_ES_EXECUTED;
-
- atomic_add_and_fetch_u(&this->m_chunksFinished, 1);
- if (memoryBuffers) {
- for (unsigned int index = 0; index < this->m_cachedMaxReadBufferOffset; index++) {
- MemoryBuffer *buffer = memoryBuffers[index];
- if (buffer) {
- if (buffer->isTemporarily()) {
- memoryBuffers[index] = NULL;
- delete buffer;
- }
- }
- }
- MEM_freeN(memoryBuffers);
- }
- if (this->m_bTree) {
- // status report is only performed for top level Execution Groups.
- float progress = this->m_chunksFinished;
- progress /= this->m_numberOfChunks;
- this->m_bTree->progress(this->m_bTree->prh, progress);
-
- char buf[128];
- BLI_snprintf(buf, sizeof(buf), IFACE_("Compositing | Tile %u-%u"),
- this->m_chunksFinished,
- this->m_numberOfChunks);
- this->m_bTree->stats_draw(this->m_bTree->sdh, buf);
- }
+ if (this->m_chunkExecutionStates[chunkNumber] == COM_ES_SCHEDULED)
+ this->m_chunkExecutionStates[chunkNumber] = COM_ES_EXECUTED;
+
+ atomic_add_and_fetch_u(&this->m_chunksFinished, 1);
+ if (memoryBuffers) {
+ for (unsigned int index = 0; index < this->m_cachedMaxReadBufferOffset; index++) {
+ MemoryBuffer *buffer = memoryBuffers[index];
+ if (buffer) {
+ if (buffer->isTemporarily()) {
+ memoryBuffers[index] = NULL;
+ delete buffer;
+ }
+ }
+ }
+ MEM_freeN(memoryBuffers);
+ }
+ if (this->m_bTree) {
+ // status report is only performed for top level Execution Groups.
+ float progress = this->m_chunksFinished;
+ progress /= this->m_numberOfChunks;
+ this->m_bTree->progress(this->m_bTree->prh, progress);
+
+ char buf[128];
+ BLI_snprintf(buf,
+ sizeof(buf),
+ IFACE_("Compositing | Tile %u-%u"),
+ this->m_chunksFinished,
+ this->m_numberOfChunks);
+ this->m_bTree->stats_draw(this->m_bTree->sdh, buf);
+ }
}
-inline void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk) const
+inline void ExecutionGroup::determineChunkRect(rcti *rect,
+ const unsigned int xChunk,
+ const unsigned int yChunk) const
{
- const int border_width = BLI_rcti_size_x(&this->m_viewerBorder);
- const int border_height = BLI_rcti_size_y(&this->m_viewerBorder);
-
- if (this->m_singleThreaded) {
- BLI_rcti_init(rect, this->m_viewerBorder.xmin, border_width, this->m_viewerBorder.ymin, border_height);
- }
- else {
- const unsigned int minx = xChunk * this->m_chunkSize + this->m_viewerBorder.xmin;
- const unsigned int miny = yChunk * this->m_chunkSize + this->m_viewerBorder.ymin;
- const unsigned int width = min((unsigned int) this->m_viewerBorder.xmax, this->m_width);
- const unsigned int height = min((unsigned int) this->m_viewerBorder.ymax, this->m_height);
- BLI_rcti_init(rect, min(minx, this->m_width), min(minx + this->m_chunkSize, width), min(miny, this->m_height), min(miny + this->m_chunkSize, height));
- }
+ const int border_width = BLI_rcti_size_x(&this->m_viewerBorder);
+ const int border_height = BLI_rcti_size_y(&this->m_viewerBorder);
+
+ if (this->m_singleThreaded) {
+ BLI_rcti_init(
+ rect, this->m_viewerBorder.xmin, border_width, this->m_viewerBorder.ymin, border_height);
+ }
+ else {
+ const unsigned int minx = xChunk * this->m_chunkSize + this->m_viewerBorder.xmin;
+ const unsigned int miny = yChunk * this->m_chunkSize + this->m_viewerBorder.ymin;
+ const unsigned int width = min((unsigned int)this->m_viewerBorder.xmax, this->m_width);
+ const unsigned int height = min((unsigned int)this->m_viewerBorder.ymax, this->m_height);
+ BLI_rcti_init(rect,
+ min(minx, this->m_width),
+ min(minx + this->m_chunkSize, width),
+ min(miny, this->m_height),
+ min(miny + this->m_chunkSize, height));
+ }
}
void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int chunkNumber) const
{
- const unsigned int yChunk = chunkNumber / this->m_numberOfXChunks;
- const unsigned int xChunk = chunkNumber - (yChunk * this->m_numberOfXChunks);
- determineChunkRect(rect, xChunk, yChunk);
+ const unsigned int yChunk = chunkNumber / this->m_numberOfXChunks;
+ const unsigned int xChunk = chunkNumber - (yChunk * this->m_numberOfXChunks);
+ determineChunkRect(rect, xChunk, yChunk);
}
-MemoryBuffer *ExecutionGroup::allocateOutputBuffer(int /*chunkNumber*/,
- rcti *rect)
+MemoryBuffer *ExecutionGroup::allocateOutputBuffer(int /*chunkNumber*/, rcti *rect)
{
- // we assume that this method is only called from complex execution groups.
- NodeOperation *operation = this->getOutputOperation();
- if (operation->isWriteBufferOperation()) {
- WriteBufferOperation *writeOperation = (WriteBufferOperation *)operation;
- MemoryBuffer *buffer = new MemoryBuffer(writeOperation->getMemoryProxy(), rect);
- return buffer;
- }
- return NULL;
+ // we assume that this method is only called from complex execution groups.
+ NodeOperation *operation = this->getOutputOperation();
+ if (operation->isWriteBufferOperation()) {
+ WriteBufferOperation *writeOperation = (WriteBufferOperation *)operation;
+ MemoryBuffer *buffer = new MemoryBuffer(writeOperation->getMemoryProxy(), rect);
+ return buffer;
+ }
+ return NULL;
}
-
bool ExecutionGroup::scheduleAreaWhenPossible(ExecutionSystem *graph, rcti *area)
{
- if (this->m_singleThreaded) {
- return scheduleChunkWhenPossible(graph, 0, 0);
- }
- // find all chunks inside the rect
- // determine minxchunk, minychunk, maxxchunk, maxychunk where x and y are chunknumbers
-
- int indexx, indexy;
- int minx = max_ii(area->xmin - m_viewerBorder.xmin, 0);
- int maxx = min_ii(area->xmax - m_viewerBorder.xmin, m_viewerBorder.xmax - m_viewerBorder.xmin);
- int miny = max_ii(area->ymin - m_viewerBorder.ymin, 0);
- int maxy = min_ii(area->ymax - m_viewerBorder.ymin, m_viewerBorder.ymax - m_viewerBorder.ymin);
- int minxchunk = minx / (int)m_chunkSize;
- int maxxchunk = (maxx + (int)m_chunkSize - 1) / (int)m_chunkSize;
- int minychunk = miny / (int)m_chunkSize;
- int maxychunk = (maxy + (int)m_chunkSize - 1) / (int)m_chunkSize;
- minxchunk = max_ii(minxchunk, 0);
- minychunk = max_ii(minychunk, 0);
- maxxchunk = min_ii(maxxchunk, (int)m_numberOfXChunks);
- maxychunk = min_ii(maxychunk, (int)m_numberOfYChunks);
-
- bool result = true;
- for (indexx = minxchunk; indexx < maxxchunk; indexx++) {
- for (indexy = minychunk; indexy < maxychunk; indexy++) {
- if (!scheduleChunkWhenPossible(graph, indexx, indexy)) {
- result = false;
- }
- }
- }
-
- return result;
+ if (this->m_singleThreaded) {
+ return scheduleChunkWhenPossible(graph, 0, 0);
+ }
+ // find all chunks inside the rect
+ // determine minxchunk, minychunk, maxxchunk, maxychunk where x and y are chunknumbers
+
+ int indexx, indexy;
+ int minx = max_ii(area->xmin - m_viewerBorder.xmin, 0);
+ int maxx = min_ii(area->xmax - m_viewerBorder.xmin, m_viewerBorder.xmax - m_viewerBorder.xmin);
+ int miny = max_ii(area->ymin - m_viewerBorder.ymin, 0);
+ int maxy = min_ii(area->ymax - m_viewerBorder.ymin, m_viewerBorder.ymax - m_viewerBorder.ymin);
+ int minxchunk = minx / (int)m_chunkSize;
+ int maxxchunk = (maxx + (int)m_chunkSize - 1) / (int)m_chunkSize;
+ int minychunk = miny / (int)m_chunkSize;
+ int maxychunk = (maxy + (int)m_chunkSize - 1) / (int)m_chunkSize;
+ minxchunk = max_ii(minxchunk, 0);
+ minychunk = max_ii(minychunk, 0);
+ maxxchunk = min_ii(maxxchunk, (int)m_numberOfXChunks);
+ maxychunk = min_ii(maxychunk, (int)m_numberOfYChunks);
+
+ bool result = true;
+ for (indexx = minxchunk; indexx < maxxchunk; indexx++) {
+ for (indexy = minychunk; indexy < maxychunk; indexy++) {
+ if (!scheduleChunkWhenPossible(graph, indexx, indexy)) {
+ result = false;
+ }
+ }
+ }
+
+ return result;
}
bool ExecutionGroup::scheduleChunk(unsigned int chunkNumber)
{
- if (this->m_chunkExecutionStates[chunkNumber] == COM_ES_NOT_SCHEDULED) {
- this->m_chunkExecutionStates[chunkNumber] = COM_ES_SCHEDULED;
- WorkScheduler::schedule(this, chunkNumber);
- return true;
- }
- return false;
+ if (this->m_chunkExecutionStates[chunkNumber] == COM_ES_NOT_SCHEDULED) {
+ this->m_chunkExecutionStates[chunkNumber] = COM_ES_SCHEDULED;
+ WorkScheduler::schedule(this, chunkNumber);
+ return true;
+ }
+ return false;
}
bool ExecutionGroup::scheduleChunkWhenPossible(ExecutionSystem *graph, int xChunk, int yChunk)
{
- if (xChunk < 0 || xChunk >= (int)this->m_numberOfXChunks) {
- return true;
- }
- if (yChunk < 0 || yChunk >= (int)this->m_numberOfYChunks) {
- return true;
- }
- int chunkNumber = yChunk * this->m_numberOfXChunks + xChunk;
- // chunk is already executed
- if (this->m_chunkExecutionStates[chunkNumber] == COM_ES_EXECUTED) {
- return true;
- }
-
- // chunk is scheduled, but not executed
- if (this->m_chunkExecutionStates[chunkNumber] == COM_ES_SCHEDULED) {
- return false;
- }
-
- // chunk is nor executed nor scheduled.
- vector<MemoryProxy *> memoryProxies;
- this->determineDependingMemoryProxies(&memoryProxies);
-
- rcti rect;
- determineChunkRect(&rect, xChunk, yChunk);
- unsigned int index;
- bool canBeExecuted = true;
- rcti area;
-
- for (index = 0; index < this->m_cachedReadOperations.size(); index++) {
- ReadBufferOperation *readOperation = (ReadBufferOperation *)this->m_cachedReadOperations[index];
- BLI_rcti_init(&area, 0, 0, 0, 0);
- MemoryProxy *memoryProxy = memoryProxies[index];
- determineDependingAreaOfInterest(&rect, readOperation, &area);
- ExecutionGroup *group = memoryProxy->getExecutor();
-
- if (group != NULL) {
- if (!group->scheduleAreaWhenPossible(graph, &area)) {
- canBeExecuted = false;
- }
- }
- else {
- throw "ERROR";
- }
- }
-
- if (canBeExecuted) {
- scheduleChunk(chunkNumber);
- }
-
- return false;
+ if (xChunk < 0 || xChunk >= (int)this->m_numberOfXChunks) {
+ return true;
+ }
+ if (yChunk < 0 || yChunk >= (int)this->m_numberOfYChunks) {
+ return true;
+ }
+ int chunkNumber = yChunk * this->m_numberOfXChunks + xChunk;
+ // chunk is already executed
+ if (this->m_chunkExecutionStates[chunkNumber] == COM_ES_EXECUTED) {
+ return true;
+ }
+
+ // chunk is scheduled, but not executed
+ if (this->m_chunkExecutionStates[chunkNumber] == COM_ES_SCHEDULED) {
+ return false;
+ }
+
+ // chunk is nor executed nor scheduled.
+ vector<MemoryProxy *> memoryProxies;
+ this->determineDependingMemoryProxies(&memoryProxies);
+
+ rcti rect;
+ determineChunkRect(&rect, xChunk, yChunk);
+ unsigned int index;
+ bool canBeExecuted = true;
+ rcti area;
+
+ for (index = 0; index < this->m_cachedReadOperations.size(); index++) {
+ ReadBufferOperation *readOperation =
+ (ReadBufferOperation *)this->m_cachedReadOperations[index];
+ BLI_rcti_init(&area, 0, 0, 0, 0);
+ MemoryProxy *memoryProxy = memoryProxies[index];
+ determineDependingAreaOfInterest(&rect, readOperation, &area);
+ ExecutionGroup *group = memoryProxy->getExecutor();
+
+ if (group != NULL) {
+ if (!group->scheduleAreaWhenPossible(graph, &area)) {
+ canBeExecuted = false;
+ }
+ }
+ else {
+ throw "ERROR";
+ }
+ }
+
+ if (canBeExecuted) {
+ scheduleChunk(chunkNumber);
+ }
+
+ return false;
}
-void ExecutionGroup::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+void ExecutionGroup::determineDependingAreaOfInterest(rcti *input,
+ ReadBufferOperation *readOperation,
+ rcti *output)
{
- this->getOutputOperation()->determineDependingAreaOfInterest(input, readOperation, output);
+ this->getOutputOperation()->determineDependingAreaOfInterest(input, readOperation, output);
}
void ExecutionGroup::determineDependingMemoryProxies(vector<MemoryProxy *> *memoryProxies)
{
- unsigned int index;
- for (index = 0; index < this->m_cachedReadOperations.size(); index++) {
- ReadBufferOperation *readOperation = (ReadBufferOperation *) this->m_cachedReadOperations[index];
- memoryProxies->push_back(readOperation->getMemoryProxy());
- }
+ unsigned int index;
+ for (index = 0; index < this->m_cachedReadOperations.size(); index++) {
+ ReadBufferOperation *readOperation =
+ (ReadBufferOperation *)this->m_cachedReadOperations[index];
+ memoryProxies->push_back(readOperation->getMemoryProxy());
+ }
}
bool ExecutionGroup::isOpenCL()
{
- return this->m_openCL;
+ return this->m_openCL;
}
void ExecutionGroup::setViewerBorder(float xmin, float xmax, float ymin, float ymax)
{
- NodeOperation *operation = this->getOutputOperation();
-
- if (operation->isViewerOperation() || operation->isPreviewOperation()) {
- BLI_rcti_init(&this->m_viewerBorder, xmin * this->m_width, xmax * this->m_width,
- ymin * this->m_height, ymax * this->m_height);
- }
+ NodeOperation *operation = this->getOutputOperation();
+
+ if (operation->isViewerOperation() || operation->isPreviewOperation()) {
+ BLI_rcti_init(&this->m_viewerBorder,
+ xmin * this->m_width,
+ xmax * this->m_width,
+ ymin * this->m_height,
+ ymax * this->m_height);
+ }
}
void ExecutionGroup::setRenderBorder(float xmin, float xmax, float ymin, float ymax)
{
- NodeOperation *operation = this->getOutputOperation();
-
- if (operation->isOutputOperation(true)) {
- /* Basically, setting border need to happen for only operations
- * which operates in render resolution buffers (like compositor
- * output nodes).
- *
- * In this cases adding border will lead to mapping coordinates
- * from output buffer space to input buffer spaces when executing
- * operation.
- *
- * But nodes like viewer and file output just shall display or
- * safe the same exact buffer which goes to their input, no need
- * in any kind of coordinates mapping.
- */
-
- bool operationNeedsBorder = !(operation->isViewerOperation() ||
- operation->isPreviewOperation() ||
- operation->isFileOutputOperation());
-
- if (operationNeedsBorder) {
- BLI_rcti_init(&this->m_viewerBorder, xmin * this->m_width, xmax * this->m_width,
- ymin * this->m_height, ymax * this->m_height);
- }
- }
+ NodeOperation *operation = this->getOutputOperation();
+
+ if (operation->isOutputOperation(true)) {
+ /* Basically, setting border need to happen for only operations
+ * which operates in render resolution buffers (like compositor
+ * output nodes).
+ *
+ * In this cases adding border will lead to mapping coordinates
+ * from output buffer space to input buffer spaces when executing
+ * operation.
+ *
+ * But nodes like viewer and file output just shall display or
+ * safe the same exact buffer which goes to their input, no need
+ * in any kind of coordinates mapping.
+ */
+
+ bool operationNeedsBorder = !(operation->isViewerOperation() ||
+ operation->isPreviewOperation() ||
+ operation->isFileOutputOperation());
+
+ if (operationNeedsBorder) {
+ BLI_rcti_init(&this->m_viewerBorder,
+ xmin * this->m_width,
+ xmax * this->m_width,
+ ymin * this->m_height,
+ ymax * this->m_height);
+ }
+ }
}