Compositor: Full frame output nodes
Adds full frame implementation to "Composite", "File Output" and "Split Viewer" nodes. The other nodes in "Output" submenu are implemented separately. No functional changes. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D12091
This commit is contained in:
parent
d481c6651d
commit
eb03529ab9
|
@ -62,6 +62,11 @@ constexpr int COM_data_type_num_channels(const DataType datatype)
|
|||
}
|
||||
}
|
||||
|
||||
constexpr int COM_data_type_bytes_len(DataType data_type)
|
||||
{
|
||||
return COM_data_type_num_channels(data_type) * sizeof(float);
|
||||
}
|
||||
|
||||
constexpr int COM_DATA_TYPE_VALUE_CHANNELS = COM_data_type_num_channels(DataType::Value);
|
||||
constexpr int COM_DATA_TYPE_VECTOR_CHANNELS = COM_data_type_num_channels(DataType::Vector);
|
||||
constexpr int COM_DATA_TYPE_COLOR_CHANNELS = COM_data_type_num_channels(DataType::Color);
|
||||
|
|
|
@ -220,6 +220,22 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int /*tileNumber*/)
|
|||
}
|
||||
}
|
||||
|
||||
void CompositorOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
|
||||
const rcti &area,
|
||||
Span<MemoryBuffer *> inputs)
|
||||
{
|
||||
if (!m_outputBuffer) {
|
||||
return;
|
||||
}
|
||||
MemoryBuffer output_buf(m_outputBuffer, COM_DATA_TYPE_COLOR_CHANNELS, getWidth(), getHeight());
|
||||
output_buf.copy_from(inputs[0], area);
|
||||
if (this->m_useAlphaInput) {
|
||||
output_buf.copy_from(inputs[1], area, 0, COM_DATA_TYPE_VALUE_CHANNELS, 3);
|
||||
}
|
||||
MemoryBuffer depth_buf(m_depthBuffer, COM_DATA_TYPE_VALUE_CHANNELS, getWidth(), getHeight());
|
||||
depth_buf.copy_from(inputs[2], area);
|
||||
}
|
||||
|
||||
void CompositorOperation::determineResolution(unsigned int resolution[2],
|
||||
unsigned int preferredResolution[2])
|
||||
{
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "BLI_rect.h"
|
||||
#include "BLI_string.h"
|
||||
#include "COM_NodeOperation.h"
|
||||
#include "COM_MultiThreadedOperation.h"
|
||||
|
||||
struct Scene;
|
||||
|
||||
|
@ -29,7 +29,7 @@ namespace blender::compositor {
|
|||
/**
|
||||
* \brief Compositor output operation
|
||||
*/
|
||||
class CompositorOperation : public NodeOperation {
|
||||
class CompositorOperation : public MultiThreadedOperation {
|
||||
private:
|
||||
const struct Scene *m_scene;
|
||||
/**
|
||||
|
@ -125,6 +125,10 @@ class CompositorOperation : public NodeOperation {
|
|||
{
|
||||
this->m_active = active;
|
||||
}
|
||||
|
||||
void update_memory_buffer_partial(MemoryBuffer *output,
|
||||
const rcti &area,
|
||||
Span<MemoryBuffer *> inputs) override;
|
||||
};
|
||||
|
||||
} // namespace blender::compositor
|
||||
|
|
|
@ -294,6 +294,22 @@ void OutputSingleLayerOperation::deinitExecution()
|
|||
this->m_imageInput = nullptr;
|
||||
}
|
||||
|
||||
void OutputSingleLayerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
|
||||
const rcti &area,
|
||||
Span<MemoryBuffer *> inputs)
|
||||
{
|
||||
if (!m_outputBuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
MemoryBuffer output_buf(m_outputBuffer,
|
||||
COM_data_type_num_channels(this->m_datatype),
|
||||
this->getWidth(),
|
||||
this->getHeight());
|
||||
const MemoryBuffer *input_image = inputs[0];
|
||||
output_buf.copy_from(input_image, area);
|
||||
}
|
||||
|
||||
/******************************* MultiLayer *******************************/
|
||||
|
||||
OutputOpenExrLayer::OutputOpenExrLayer(const char *name_, DataType datatype_, bool use_layer_)
|
||||
|
@ -444,4 +460,21 @@ void OutputOpenExrMultiLayerOperation::deinitExecution()
|
|||
}
|
||||
}
|
||||
|
||||
void OutputOpenExrMultiLayerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
|
||||
const rcti &area,
|
||||
Span<MemoryBuffer *> inputs)
|
||||
{
|
||||
const MemoryBuffer *input_image = inputs[0];
|
||||
for (int i = 0; i < this->m_layers.size(); i++) {
|
||||
OutputOpenExrLayer &layer = this->m_layers[i];
|
||||
if (layer.outputBuffer) {
|
||||
MemoryBuffer output_buf(layer.outputBuffer,
|
||||
COM_data_type_num_channels(layer.datatype),
|
||||
this->getWidth(),
|
||||
this->getHeight());
|
||||
output_buf.copy_from(input_image, area);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::compositor
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "COM_NodeOperation.h"
|
||||
#include "COM_MultiThreadedOperation.h"
|
||||
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_rect.h"
|
||||
|
@ -30,7 +30,7 @@
|
|||
namespace blender::compositor {
|
||||
|
||||
/* Writes the image to a single-layer file. */
|
||||
class OutputSingleLayerOperation : public NodeOperation {
|
||||
class OutputSingleLayerOperation : public MultiThreadedOperation {
|
||||
protected:
|
||||
const RenderData *m_rd;
|
||||
const bNodeTree *m_tree;
|
||||
|
@ -70,6 +70,10 @@ class OutputSingleLayerOperation : public NodeOperation {
|
|||
{
|
||||
return eCompositorPriority::Low;
|
||||
}
|
||||
|
||||
void update_memory_buffer_partial(MemoryBuffer *output,
|
||||
const rcti &area,
|
||||
Span<MemoryBuffer *> inputs) override;
|
||||
};
|
||||
|
||||
/* extra info for OpenEXR layers */
|
||||
|
@ -86,7 +90,7 @@ struct OutputOpenExrLayer {
|
|||
};
|
||||
|
||||
/* Writes inputs into OpenEXR multilayer channels. */
|
||||
class OutputOpenExrMultiLayerOperation : public NodeOperation {
|
||||
class OutputOpenExrMultiLayerOperation : public MultiThreadedOperation {
|
||||
protected:
|
||||
const Scene *m_scene;
|
||||
const RenderData *m_rd;
|
||||
|
@ -122,6 +126,10 @@ class OutputOpenExrMultiLayerOperation : public NodeOperation {
|
|||
{
|
||||
return eCompositorPriority::Low;
|
||||
}
|
||||
|
||||
void update_memory_buffer_partial(MemoryBuffer *output,
|
||||
const rcti &area,
|
||||
Span<MemoryBuffer *> inputs) override;
|
||||
};
|
||||
|
||||
void add_exr_channels(void *exrhandle,
|
||||
|
|
|
@ -79,4 +79,17 @@ void SplitOperation::determineResolution(unsigned int resolution[2],
|
|||
NodeOperation::determineResolution(resolution, preferredResolution);
|
||||
}
|
||||
|
||||
void SplitOperation::update_memory_buffer_partial(MemoryBuffer *output,
|
||||
const rcti &area,
|
||||
Span<MemoryBuffer *> inputs)
|
||||
{
|
||||
const int percent = this->m_xSplit ? this->m_splitPercentage * this->getWidth() / 100.0f :
|
||||
this->m_splitPercentage * this->getHeight() / 100.0f;
|
||||
const size_t elem_bytes = COM_data_type_bytes_len(getOutputSocket()->getDataType());
|
||||
for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
|
||||
const bool is_image1 = this->m_xSplit ? it.x > percent : it.y > percent;
|
||||
memcpy(it.out, it.in(is_image1 ? 0 : 1), elem_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::compositor
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "COM_NodeOperation.h"
|
||||
#include "COM_MultiThreadedOperation.h"
|
||||
|
||||
namespace blender::compositor {
|
||||
|
||||
class SplitOperation : public NodeOperation {
|
||||
class SplitOperation : public MultiThreadedOperation {
|
||||
private:
|
||||
SocketReader *m_image1Input;
|
||||
SocketReader *m_image2Input;
|
||||
|
@ -45,6 +45,10 @@ class SplitOperation : public NodeOperation {
|
|||
{
|
||||
this->m_xSplit = xsplit;
|
||||
}
|
||||
|
||||
void update_memory_buffer_partial(MemoryBuffer *output,
|
||||
const rcti &area,
|
||||
Span<MemoryBuffer *> inputs) override;
|
||||
};
|
||||
|
||||
} // namespace blender::compositor
|
||||
|
|
Loading…
Reference in New Issue