This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/compositor/intern/COM_ExecutionSystem.cpp
Campbell Barton 3316853323 Cleanup: conform headers to have license first
Also remove doxy comments for licenses and add missing GPL header.
2019-02-18 08:22:11 +11:00

228 lines
7.3 KiB
C++

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright 2011, Blender Foundation.
*/
#include "COM_ExecutionSystem.h"
#include "PIL_time.h"
#include "BLI_utildefines.h"
extern "C" {
#include "BKE_node.h"
}
#include "BLT_translation.h"
#include "COM_Converter.h"
#include "COM_NodeOperationBuilder.h"
#include "COM_NodeOperation.h"
#include "COM_ExecutionGroup.h"
#include "COM_WorkScheduler.h"
#include "COM_ReadBufferOperation.h"
#include "COM_Debug.h"
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
ExecutionSystem::ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editingtree, bool rendering, bool fastcalculation,
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings,
const char *viewName)
{
this->m_context.setViewName(viewName);
this->m_context.setScene(scene);
this->m_context.setbNodeTree(editingtree);
this->m_context.setPreviewHash(editingtree->previews);
this->m_context.setFastCalculation(fastcalculation);
/* initialize the CompositorContext */
if (rendering) {
this->m_context.setQuality((CompositorQuality)editingtree->render_quality);
}
else {
this->m_context.setQuality((CompositorQuality)editingtree->edit_quality);
}
this->m_context.setRendering(rendering);
this->m_context.setHasActiveOpenCLDevices(WorkScheduler::hasGPUDevices() && (editingtree->flag & NTREE_COM_OPENCL));
this->m_context.setRenderData(rd);
this->m_context.setViewSettings(viewSettings);
this->m_context.setDisplaySettings(displaySettings);
{
NodeOperationBuilder builder(&m_context, editingtree);
builder.convertToOperations(this);
}
unsigned int index;
unsigned int resolution[2];
rctf *viewer_border = &editingtree->viewer_border;
bool use_viewer_border = (editingtree->flag & NTREE_VIEWER_BORDER) &&
viewer_border->xmin < viewer_border->xmax &&
viewer_border->ymin < viewer_border->ymax;
editingtree->stats_draw(editingtree->sdh, IFACE_("Compositing | Determining resolution"));
for (index = 0; index < this->m_groups.size(); index++) {
resolution[0] = 0;
resolution[1] = 0;
ExecutionGroup *executionGroup = this->m_groups[index];
executionGroup->determineResolution(resolution);
if (rendering) {
/* case when cropping to render border happens is handled in
* compositor output and render layer nodes
*/
if ((rd->mode & R_BORDER) && !(rd->mode & R_CROP)) {
executionGroup->setRenderBorder(rd->border.xmin, rd->border.xmax,
rd->border.ymin, rd->border.ymax);
}
}
if (use_viewer_border) {
executionGroup->setViewerBorder(viewer_border->xmin, viewer_border->xmax,
viewer_border->ymin, viewer_border->ymax);
}
}
// DebugInfo::graphviz(this);
}
ExecutionSystem::~ExecutionSystem()
{
unsigned int index;
for (index = 0; index < this->m_operations.size(); index++) {
NodeOperation *operation = this->m_operations[index];
delete operation;
}
this->m_operations.clear();
for (index = 0; index < this->m_groups.size(); index++) {
ExecutionGroup *group = this->m_groups[index];
delete group;
}
this->m_groups.clear();
}
void ExecutionSystem::set_operations(const Operations &operations, const Groups &groups)
{
m_operations = operations;
m_groups = groups;
}
void ExecutionSystem::execute()
{
const bNodeTree *editingtree = this->m_context.getbNodeTree();
editingtree->stats_draw(editingtree->sdh, IFACE_("Compositing | Initializing execution"));
DebugInfo::execute_started(this);
unsigned int order = 0;
for (vector<NodeOperation *>::iterator iter = this->m_operations.begin(); iter != this->m_operations.end(); ++iter) {
NodeOperation *operation = *iter;
if (operation->isReadBufferOperation()) {
ReadBufferOperation *readOperation = (ReadBufferOperation *)operation;
readOperation->setOffset(order);
order++;
}
}
unsigned int index;
// First allocale all write buffer
for (index = 0; index < this->m_operations.size(); index++) {
NodeOperation *operation = this->m_operations[index];
if (operation->isWriteBufferOperation()) {
operation->setbNodeTree(this->m_context.getbNodeTree());
operation->initExecution();
}
}
// Connect read buffers to their write buffers
for (index = 0; index < this->m_operations.size(); index++) {
NodeOperation *operation = this->m_operations[index];
if (operation->isReadBufferOperation()) {
ReadBufferOperation *readOperation = (ReadBufferOperation *)operation;
readOperation->updateMemoryBuffer();
}
}
// initialize other operations
for (index = 0; index < this->m_operations.size(); index++) {
NodeOperation *operation = this->m_operations[index];
if (!operation->isWriteBufferOperation()) {
operation->setbNodeTree(this->m_context.getbNodeTree());
operation->initExecution();
}
}
for (index = 0; index < this->m_groups.size(); index++) {
ExecutionGroup *executionGroup = this->m_groups[index];
executionGroup->setChunksize(this->m_context.getChunksize());
executionGroup->initExecution();
}
WorkScheduler::start(this->m_context);
executeGroups(COM_PRIORITY_HIGH);
if (!this->getContext().isFastCalculation()) {
executeGroups(COM_PRIORITY_MEDIUM);
executeGroups(COM_PRIORITY_LOW);
}
WorkScheduler::finish();
WorkScheduler::stop();
editingtree->stats_draw(editingtree->sdh, IFACE_("Compositing | De-initializing execution"));
for (index = 0; index < this->m_operations.size(); index++) {
NodeOperation *operation = this->m_operations[index];
operation->deinitExecution();
}
for (index = 0; index < this->m_groups.size(); index++) {
ExecutionGroup *executionGroup = this->m_groups[index];
executionGroup->deinitExecution();
}
}
void ExecutionSystem::executeGroups(CompositorPriority priority)
{
unsigned int index;
vector<ExecutionGroup *> executionGroups;
this->findOutputExecutionGroup(&executionGroups, priority);
for (index = 0; index < executionGroups.size(); index++) {
ExecutionGroup *group = executionGroups[index];
group->execute(this);
}
}
void ExecutionSystem::findOutputExecutionGroup(vector<ExecutionGroup *> *result, CompositorPriority priority) const
{
unsigned int index;
for (index = 0; index < this->m_groups.size(); index++) {
ExecutionGroup *group = this->m_groups[index];
if (group->isOutputExecutionGroup() && group->getRenderPriotrity() == priority) {
result->push_back(group);
}
}
}
void ExecutionSystem::findOutputExecutionGroup(vector<ExecutionGroup *> *result) const
{
unsigned int index;
for (index = 0; index < this->m_groups.size(); index++) {
ExecutionGroup *group = this->m_groups[index];
if (group->isOutputExecutionGroup()) {
result->push_back(group);
}
}
}