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.cc

226 lines
7.1 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 "BLI_utildefines.h"
#include "PIL_time.h"
#include "BKE_node.h"
#include "BLT_translation.h"
#include "COM_Converter.h"
#include "COM_Debug.h"
#include "COM_ExecutionGroup.h"
#include "COM_NodeOperation.h"
#include "COM_NodeOperationBuilder.h"
#include "COM_ReadBufferOperation.h"
#include "COM_WorkScheduler.h"
#ifdef WITH_CXX_GUARDEDALLOC
# include "MEM_guardedalloc.h"
#endif
namespace blender::compositor {
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::has_gpu_devices() &&
(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 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, TIP_("Compositing | Determining resolution"));
for (ExecutionGroup *executionGroup : m_groups) {
resolution[0] = 0;
resolution[1] = 0;
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()
{
for (NodeOperation *operation : m_operations) {
delete operation;
}
this->m_operations.clear();
for (ExecutionGroup *group : m_groups) {
delete group;
}
this->m_groups.clear();
}
void ExecutionSystem::set_operations(const blender::Vector<NodeOperation *> &operations,
const blender::Vector<ExecutionGroup *> &groups)
{
m_operations = operations;
m_groups = groups;
}
static void update_read_buffer_offset(blender::Vector<NodeOperation *> &operations)
{
unsigned int order = 0;
for (NodeOperation *operation : operations) {
if (operation->isReadBufferOperation()) {
ReadBufferOperation *readOperation = (ReadBufferOperation *)operation;
readOperation->setOffset(order);
order++;
}
}
}
static void init_write_operations_for_execution(blender::Vector<NodeOperation *> &operations,
const bNodeTree *bTree)
{
for (NodeOperation *operation : operations) {
if (operation->isWriteBufferOperation()) {
operation->setbNodeTree(bTree);
operation->initExecution();
}
}
}
static void link_write_buffers(blender::Vector<NodeOperation *> &operations)
{
for (NodeOperation *operation : operations) {
if (operation->isReadBufferOperation()) {
ReadBufferOperation *readOperation = static_cast<ReadBufferOperation *>(operation);
readOperation->updateMemoryBuffer();
}
}
}
static void init_non_write_operations_for_execution(blender::Vector<NodeOperation *> &operations,
const bNodeTree *bTree)
{
for (NodeOperation *operation : operations) {
if (!operation->isWriteBufferOperation()) {
operation->setbNodeTree(bTree);
operation->initExecution();
}
}
}
static void init_execution_groups_for_execution(blender::Vector<ExecutionGroup *> &groups,
const int chunk_size)
{
for (ExecutionGroup *execution_group : groups) {
execution_group->setChunksize(chunk_size);
execution_group->initExecution();
}
}
void ExecutionSystem::execute()
{
const bNodeTree *editingtree = this->m_context.getbNodeTree();
editingtree->stats_draw(editingtree->sdh, TIP_("Compositing | Initializing execution"));
DebugInfo::execute_started(this);
update_read_buffer_offset(m_operations);
init_write_operations_for_execution(m_operations, m_context.getbNodeTree());
link_write_buffers(m_operations);
init_non_write_operations_for_execution(m_operations, m_context.getbNodeTree());
init_execution_groups_for_execution(m_groups, m_context.getChunksize());
WorkScheduler::start(this->m_context);
execute_groups(CompositorPriority::High);
if (!this->getContext().isFastCalculation()) {
execute_groups(CompositorPriority::Medium);
execute_groups(CompositorPriority::Low);
}
WorkScheduler::finish();
WorkScheduler::stop();
editingtree->stats_draw(editingtree->sdh, TIP_("Compositing | De-initializing execution"));
for (NodeOperation *operation : m_operations) {
operation->deinitExecution();
}
for (ExecutionGroup *execution_group : m_groups) {
execution_group->deinitExecution();
}
}
void ExecutionSystem::execute_groups(CompositorPriority priority)
{
for (ExecutionGroup *execution_group : m_groups) {
if (execution_group->isOutputExecutionGroup() &&
execution_group->getRenderPriority() == priority) {
execution_group->execute(this);
}
}
}
} // namespace blender::compositor