Make a copy of ImageFormatData that contains the effective color management settings, and pass that along to the various functions. This will make it possible to add more complex logic later. For compositing nodes, passing along view and display settings through many functions made it harder to add additional settings, so just get those from the scene now. Differential Revision: https://developer.blender.org/D14401
108 lines
3.4 KiB
C++
108 lines
3.4 KiB
C++
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Copyright 2011 Blender Foundation. */
|
|
|
|
#include "BLI_threads.h"
|
|
|
|
#include "BLT_translation.h"
|
|
|
|
#include "BKE_node.h"
|
|
#include "BKE_scene.h"
|
|
|
|
#include "COM_ExecutionSystem.h"
|
|
#include "COM_WorkScheduler.h"
|
|
#include "COM_compositor.h"
|
|
|
|
static struct {
|
|
bool is_initialized = false;
|
|
ThreadMutex mutex;
|
|
} g_compositor;
|
|
|
|
/* Make sure node tree has previews.
|
|
* Don't create previews in advance, this is done when adding preview operations.
|
|
* Reserved preview size is determined by render output for now. */
|
|
static void compositor_init_node_previews(const RenderData *render_data, bNodeTree *node_tree)
|
|
{
|
|
/* We fit the aspect into COM_PREVIEW_SIZE x COM_PREVIEW_SIZE image to avoid
|
|
* insane preview resolution, which might even overflow preview dimensions. */
|
|
const float aspect = render_data->xsch > 0 ?
|
|
(float)render_data->ysch / (float)render_data->xsch :
|
|
1.0f;
|
|
int preview_width, preview_height;
|
|
if (aspect < 1.0f) {
|
|
preview_width = blender::compositor::COM_PREVIEW_SIZE;
|
|
preview_height = (int)(blender::compositor::COM_PREVIEW_SIZE * aspect);
|
|
}
|
|
else {
|
|
preview_width = (int)(blender::compositor::COM_PREVIEW_SIZE / aspect);
|
|
preview_height = blender::compositor::COM_PREVIEW_SIZE;
|
|
}
|
|
BKE_node_preview_init_tree(node_tree, preview_width, preview_height);
|
|
}
|
|
|
|
static void compositor_reset_node_tree_status(bNodeTree *node_tree)
|
|
{
|
|
node_tree->progress(node_tree->prh, 0.0);
|
|
node_tree->stats_draw(node_tree->sdh, IFACE_("Compositing"));
|
|
}
|
|
|
|
void COM_execute(RenderData *render_data,
|
|
Scene *scene,
|
|
bNodeTree *node_tree,
|
|
int rendering,
|
|
const char *view_name)
|
|
{
|
|
/* Initialize mutex, TODO: this mutex init is actually not thread safe and
|
|
* should be done somewhere as part of blender startup, all the other
|
|
* initializations can be done lazily. */
|
|
if (!g_compositor.is_initialized) {
|
|
BLI_mutex_init(&g_compositor.mutex);
|
|
g_compositor.is_initialized = true;
|
|
}
|
|
|
|
BLI_mutex_lock(&g_compositor.mutex);
|
|
|
|
if (node_tree->test_break(node_tree->tbh)) {
|
|
/* During editing multiple compositor executions can be triggered.
|
|
* Make sure this is the most recent one. */
|
|
BLI_mutex_unlock(&g_compositor.mutex);
|
|
return;
|
|
}
|
|
|
|
compositor_init_node_previews(render_data, node_tree);
|
|
compositor_reset_node_tree_status(node_tree);
|
|
|
|
/* Initialize workscheduler. */
|
|
const bool use_opencl = (node_tree->flag & NTREE_COM_OPENCL) != 0;
|
|
blender::compositor::WorkScheduler::initialize(use_opencl, BKE_render_num_threads(render_data));
|
|
|
|
/* Execute. */
|
|
const bool twopass = (node_tree->flag & NTREE_TWO_PASS) && !rendering;
|
|
if (twopass) {
|
|
blender::compositor::ExecutionSystem fast_pass(
|
|
render_data, scene, node_tree, rendering, true, view_name);
|
|
fast_pass.execute();
|
|
|
|
if (node_tree->test_break(node_tree->tbh)) {
|
|
BLI_mutex_unlock(&g_compositor.mutex);
|
|
return;
|
|
}
|
|
}
|
|
|
|
blender::compositor::ExecutionSystem system(
|
|
render_data, scene, node_tree, rendering, false, view_name);
|
|
system.execute();
|
|
|
|
BLI_mutex_unlock(&g_compositor.mutex);
|
|
}
|
|
|
|
void COM_deinitialize()
|
|
{
|
|
if (g_compositor.is_initialized) {
|
|
BLI_mutex_lock(&g_compositor.mutex);
|
|
blender::compositor::WorkScheduler::deinitialize();
|
|
g_compositor.is_initialized = false;
|
|
BLI_mutex_unlock(&g_compositor.mutex);
|
|
BLI_mutex_end(&g_compositor.mutex);
|
|
}
|
|
}
|