Files
test/source/blender/compositor/intern/COM_compositor.cc
Omar Emara f40cf759c7 Compositor: Add experimental option for new CPU compositor
This patch introduces a new experimental option for the new CPU
compositor under development. This is to make development easier such
that it happens directly in main, but the compositor is not expected to
work and will probably crash.

Pull Request: https://projects.blender.org/blender/blender/pulls/125960
2024-08-08 15:40:06 +02:00

115 lines
3.7 KiB
C++

/* SPDX-FileCopyrightText: 2011 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_threads.h"
#include "BLT_translation.hh"
#include "DNA_userdef_types.h"
#include "BKE_node.hh"
#include "BKE_node_runtime.hh"
#include "BKE_scene.hh"
#include "COM_ExecutionSystem.h"
#include "COM_WorkScheduler.h"
#include "COM_compositor.hh"
#include "RE_compositor.hh"
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;
}
blender::bke::node_preview_init_tree(node_tree, preview_width, preview_height);
}
static void compositor_reset_node_tree_status(bNodeTree *node_tree)
{
node_tree->runtime->progress(node_tree->runtime->prh, 0.0);
node_tree->runtime->stats_draw(node_tree->runtime->sdh, IFACE_("Compositing"));
}
void COM_execute(Render *render,
RenderData *render_data,
Scene *scene,
bNodeTree *node_tree,
const char *view_name,
blender::realtime_compositor::RenderContext *render_context,
blender::realtime_compositor::Profiler *profiler)
{
/* 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->runtime->test_break(node_tree->runtime->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);
if (scene->r.compositor_device == SCE_COMPOSITOR_DEVICE_GPU ||
(USER_EXPERIMENTAL_TEST(&U, enable_new_cpu_compositor) && !scene->r.use_old_cpu_compositor))
{
/* Realtime compositor. */
RE_compositor_execute(
*render, *scene, *render_data, *node_tree, view_name, render_context, profiler);
}
else {
/* CPU compositor. */
/* Initialize workscheduler. */
blender::compositor::WorkScheduler::initialize(BKE_render_num_threads(render_data));
/* Execute. */
const bool is_rendering = render_context != nullptr;
blender::compositor::ExecutionSystem system(
render_data, scene, node_tree, is_rendering, view_name, render_context, profiler);
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);
}
}