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; }
static void find_reachable_operations_recursive(Tags &reachable, NodeOperation *op) { if (reachable.find(op) != reachable.end()) return; reachable.insert(op); for (int i = 0; i < op->getNumberOfInputSockets(); ++i) { NodeOperationInput *input = op->getInputSocket(i); if (input->isConnected()) find_reachable_operations_recursive(reachable, &input->getLink()->getOperation()); } /* associated write-buffer operations are executed as well */ if (op->isReadBufferOperation()) { ReadBufferOperation *read_op = (ReadBufferOperation *)op; MemoryProxy *memproxy = read_op->getMemoryProxy(); find_reachable_operations_recursive(reachable, memproxy->getWriteBufferOperation()); } }
void NodeOperationBuilder::group_operations() { for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { NodeOperation *op = *it; if (op->isOutputOperation(m_context->isRendering())) { ExecutionGroup *group = make_group(op); group->setOutputExecutionGroup(true); } /* add new groups for associated memory proxies where needed */ if (op->isReadBufferOperation()) { ReadBufferOperation *read_op = (ReadBufferOperation *)op; MemoryProxy *memproxy = read_op->getMemoryProxy(); if (memproxy->getExecutor() == NULL) { ExecutionGroup *group = make_group(memproxy->getWriteBufferOperation()); memproxy->setExecutor(group); } } } }