From fe60062a9910161d411da6e14690755d814c4cb1 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 29 Mar 2021 16:45:49 +0200 Subject: Cleanup: Use Bitflags For Booleans. --- .../compositor/intern/COM_ExecutionGroup.cc | 64 +++-------- .../blender/compositor/intern/COM_ExecutionGroup.h | 83 ++++++-------- .../compositor/intern/COM_ExecutionSystem.cc | 2 +- .../blender/compositor/intern/COM_NodeOperation.cc | 5 +- .../blender/compositor/intern/COM_NodeOperation.h | 126 +++++++++++---------- .../compositor/intern/COM_NodeOperationBuilder.cc | 2 +- .../intern/COM_SingleThreadedOperation.cc | 2 +- .../blender/compositor/intern/COM_WorkScheduler.cc | 2 +- .../blender/compositor/intern/COM_WorkScheduler.h | 2 +- 9 files changed, 123 insertions(+), 165 deletions(-) (limited to 'source/blender/compositor/intern') diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cc b/source/blender/compositor/intern/COM_ExecutionGroup.cc index 071b1d41941..9f9effd430d 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cc +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cc @@ -50,8 +50,6 @@ namespace blender::compositor { ExecutionGroup::ExecutionGroup() { - this->m_is_output = false; - this->m_complex = false; this->m_bTree = nullptr; this->m_height = 0; this->m_width = 0; @@ -60,8 +58,6 @@ ExecutionGroup::ExecutionGroup() this->m_y_chunks_len = 0; this->m_chunks_len = 0; this->m_initialized = false; - this->m_openCL = false; - this->m_singleThreaded = false; this->m_chunks_finished = 0; BLI_rcti_init(&this->m_viewerBorder, 0, 0, 0, 0); this->m_executionStartTime = 0; @@ -89,12 +85,12 @@ bool ExecutionGroup::can_contain(NodeOperation &operation) } /* complex groups don't allow further ops (except read buffer and values, see above) */ - if (m_complex) { + if (m_flags.complex) { return false; } /* complex ops can't be added to other groups (except their own, which they initialize, see * above) */ - if (operation.isComplex()) { + if (operation.get_flags().complex) { return false; } @@ -108,9 +104,9 @@ bool ExecutionGroup::addOperation(NodeOperation *operation) } if (!operation->isReadBufferOperation() && !operation->isWriteBufferOperation()) { - m_complex = operation->isComplex(); - m_openCL = operation->isOpenCL(); - m_singleThreaded = operation->isSingleThreaded(); + m_flags.complex = operation->get_flags().complex; + m_flags.open_cl = operation->get_flags().open_cl; + m_flags.single_threaded = operation->isSingleThreaded(); m_initialized = true; } @@ -168,7 +164,7 @@ void ExecutionGroup::determineResolution(unsigned int resolution[2]) void ExecutionGroup::determineNumberOfChunks() { - if (this->m_singleThreaded) { + if (this->m_flags.single_threaded) { this->m_x_chunks_len = 1; this->m_y_chunks_len = 1; this->m_chunks_len = 1; @@ -429,7 +425,7 @@ inline void ExecutionGroup::determineChunkRect(rcti *rect, const int border_width = BLI_rcti_size_x(&this->m_viewerBorder); const int border_height = BLI_rcti_size_y(&this->m_viewerBorder); - if (this->m_singleThreaded) { + if (this->m_flags.single_threaded) { BLI_rcti_init( rect, this->m_viewerBorder.xmin, border_width, this->m_viewerBorder.ymin, border_height); } @@ -468,7 +464,7 @@ MemoryBuffer *ExecutionGroup::allocateOutputBuffer(rcti &rect) bool ExecutionGroup::scheduleAreaWhenPossible(ExecutionSystem *graph, rcti *area) { - if (this->m_singleThreaded) { + if (this->m_flags.single_threaded) { return scheduleChunkWhenPossible(graph, 0, 0); } // find all chunks inside the rect @@ -560,16 +556,10 @@ void ExecutionGroup::determineDependingAreaOfInterest(rcti *input, this->getOutputOperation()->determineDependingAreaOfInterest(input, readOperation, output); } -bool ExecutionGroup::isOpenCL() -{ - return this->m_openCL; -} - void ExecutionGroup::setViewerBorder(float xmin, float xmax, float ymin, float ymax) { - NodeOperation *operation = this->getOutputOperation(); - - if (operation->isViewerOperation() || operation->isPreviewOperation()) { + const NodeOperation &operation = *this->getOutputOperation(); + if (operation.get_flags().use_viewer_border) { BLI_rcti_init(&this->m_viewerBorder, xmin * this->m_width, xmax * this->m_width, @@ -580,33 +570,13 @@ void ExecutionGroup::setViewerBorder(float xmin, float xmax, float ymin, float y void ExecutionGroup::setRenderBorder(float xmin, float xmax, float ymin, float ymax) { - NodeOperation *operation = this->getOutputOperation(); - - if (operation->isOutputOperation(true)) { - /* Basically, setting border need to happen for only operations - * which operates in render resolution buffers (like compositor - * output nodes). - * - * In this cases adding border will lead to mapping coordinates - * from output buffer space to input buffer spaces when executing - * operation. - * - * But nodes like viewer and file output just shall display or - * safe the same exact buffer which goes to their input, no need - * in any kind of coordinates mapping. - */ - - bool operationNeedsBorder = !(operation->isViewerOperation() || - operation->isPreviewOperation() || - operation->isFileOutputOperation()); - - if (operationNeedsBorder) { - BLI_rcti_init(&this->m_viewerBorder, - xmin * this->m_width, - xmax * this->m_width, - ymin * this->m_height, - ymax * this->m_height); - } + const NodeOperation &operation = *this->getOutputOperation(); + if (operation.isOutputOperation(true) && operation.get_flags().use_render_border) { + BLI_rcti_init(&this->m_viewerBorder, + xmin * this->m_width, + xmax * this->m_width, + ymin * this->m_height, + ymax * this->m_height); } } diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index f8bc5f43e31..f97aa0ff985 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -60,6 +60,35 @@ enum class eChunkExecutionState { EXECUTED = 2, }; +struct ExecutionGroupFlags { + /** + * Is this ExecutionGroup an output ExecutionGroup + * An OutputExecution group are groups containing a + * ViewerOperation, CompositeOperation, PreviewOperation. + */ + bool is_output : 1; + bool complex : 1; + + /** + * Can this ExecutionGroup be scheduled on an OpenCLDevice. + */ + bool open_cl : 1; + + /** + * Schedule this execution group as a single chunk. This + * chunk will be executed by a single thread. + */ + bool single_threaded : 1; + + ExecutionGroupFlags() + { + is_output = false; + complex = false; + open_cl = false; + single_threaded = false; + } +}; + /** * \brief Class ExecutionGroup is a group of Operations that are executed as one. * This grouping is used to combine Operations that can be executed as one whole when @@ -75,12 +104,7 @@ class ExecutionGroup { */ blender::Vector m_operations; - /** - * \brief is this ExecutionGroup an input ExecutionGroup - * an input execution group is a group that is at the end of the calculation - * (the output is important for the user). - */ - bool m_is_output; + ExecutionGroupFlags m_flags; /** * \brief Width of the output @@ -113,21 +137,6 @@ class ExecutionGroup { */ unsigned int m_chunks_len; - /** - * \brief contains this ExecutionGroup a complex NodeOperation. - */ - bool m_complex; - - /** - * \brief can this ExecutionGroup be scheduled on an OpenCLDevice - */ - bool m_openCL; - - /** - * \brief Is this Execution group SingleThreaded - */ - bool m_singleThreaded; - /** * \brief what is the maximum number field of all ReadBufferOperation in this ExecutionGroup. * \note this is used to construct the MemoryBuffers that will be passed during execution. @@ -261,6 +270,11 @@ class ExecutionGroup { // constructors ExecutionGroup(); + const ExecutionGroupFlags get_flags() const + { + return m_flags; + } + // methods /** * \brief add an operation to this ExecutionGroup @@ -272,24 +286,13 @@ class ExecutionGroup { */ bool addOperation(NodeOperation *operation); - /** - * \brief is this ExecutionGroup an output ExecutionGroup - * \note An OutputExecution group are groups containing a - * \note ViewerOperation, CompositeOperation, PreviewOperation. - * \see NodeOperation.isOutputOperation - */ - bool isOutputExecutionGroup() const - { - return this->m_is_output; - } - /** * \brief set whether this ExecutionGroup is an output * \param isOutput: */ void setOutputExecutionGroup(bool is_output) { - this->m_is_output = is_output; + this->m_flags.is_output = is_output; } /** @@ -324,14 +327,6 @@ class ExecutionGroup { return m_height; } - /** - * \brief does this ExecutionGroup contains a complex NodeOperation - */ - bool isComplex() const - { - return m_complex; - } - /** * \brief get the output operation of this ExecutionGroup * \return NodeOperation *output operation @@ -412,12 +407,6 @@ class ExecutionGroup { */ void determineChunkRect(rcti *rect, const unsigned int chunkNumber) const; - /** - * \brief can this ExecutionGroup be scheduled on an OpenCLDevice - * \see WorkScheduler.schedule - */ - bool isOpenCL(); - void setChunksize(int chunksize) { this->m_chunkSize = chunksize; diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cc b/source/blender/compositor/intern/COM_ExecutionSystem.cc index c8e3b11160b..b3adca5ac51 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cc +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cc @@ -215,7 +215,7 @@ void ExecutionSystem::execute() void ExecutionSystem::execute_groups(CompositorPriority priority) { for (ExecutionGroup *execution_group : m_groups) { - if (execution_group->isOutputExecutionGroup() && + if (execution_group->get_flags().is_output && execution_group->getRenderPriority() == priority) { execution_group->execute(this); } diff --git a/source/blender/compositor/intern/COM_NodeOperation.cc b/source/blender/compositor/intern/COM_NodeOperation.cc index a16e2d359f1..cb2134ae5f1 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.cc +++ b/source/blender/compositor/intern/COM_NodeOperation.cc @@ -33,11 +33,8 @@ namespace blender::compositor { NodeOperation::NodeOperation() { this->m_resolutionInputSocketIndex = 0; - this->m_complex = false; this->m_width = 0; this->m_height = 0; - this->m_isResolutionSet = false; - this->m_openCL = false; this->m_btree = nullptr; } @@ -202,7 +199,7 @@ void NodeOperationOutput::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) { NodeOperation &operation = getOperation(); - if (operation.isResolutionSet()) { + if (operation.get_flags().is_resolution_set) { resolution[0] = operation.getWidth(); resolution[1] = operation.getHeight(); } diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index 3d334758e7a..88f9c49dbf0 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -165,6 +165,55 @@ class NodeOperationOutput { #endif }; +struct NodeOperationFlags { + /** + * Is this an complex operation. + * + * The input and output buffers of Complex operations are stored in buffers. It allows + * sequential and read/write. + * + * Complex operations are typically doing many reads to calculate the output of a single pixel. + * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true. + */ + bool complex : 1; + + /** + * Does this operation support OpenCL. + */ + bool open_cl : 1; + + /** + * Does the operation needs a viewer border. + * Basically, setting border need to happen for only operations + * which operates in render resolution buffers (like compositor + * output nodes). + * + * In this cases adding border will lead to mapping coordinates + * from output buffer space to input buffer spaces when executing + * operation. + * + * But nodes like viewer and file output just shall display or + * safe the same exact buffer which goes to their input, no need + * in any kind of coordinates mapping. + */ + bool use_render_border : 1; + bool use_viewer_border : 1; + + /** + * Is the resolution of the operation set. + */ + bool is_resolution_set : 1; + + NodeOperationFlags() + { + complex = false; + open_cl = false; + use_render_border = false; + use_viewer_border = false; + is_resolution_set = false; + } +}; + /** * \brief NodeOperation contains calculation logic * @@ -181,20 +230,6 @@ class NodeOperation { */ unsigned int m_resolutionInputSocketIndex; - /** - * \brief is this operation a complex one. - * - * Complex operations are typically doing many reads to calculate the output of a single pixel. - * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true. - */ - bool m_complex; - - /** - * \brief can this operation be scheduled on an OpenCL device. - * \note Only applicable if complex is True - */ - bool m_openCL; - /** * \brief mutex reference for very special node initializations * \note only use when you really know what you are doing. @@ -211,11 +246,6 @@ class NodeOperation { */ const bNodeTree *m_btree; - /** - * \brief set to truth when resolution for this operation is set - */ - bool m_isResolutionSet; - protected: /** * Width of the output of this operation. @@ -227,11 +257,21 @@ class NodeOperation { */ unsigned int m_height; + /** + * Flags how to evaluate this operation. + */ + NodeOperationFlags flags; + public: virtual ~NodeOperation() { } + const NodeOperationFlags get_flags() const + { + return flags; + } + unsigned int getNumberOfInputSockets() const { return m_inputs.size(); @@ -347,35 +387,19 @@ class NodeOperation { } virtual void deinitExecution(); - bool isResolutionSet() - { - return this->m_isResolutionSet; - } - /** * \brief set the resolution * \param resolution: the resolution to set */ void setResolution(unsigned int resolution[2]) { - if (!isResolutionSet()) { + if (!this->flags.is_resolution_set) { this->m_width = resolution[0]; this->m_height = resolution[1]; - this->m_isResolutionSet = true; + this->flags.is_resolution_set = true; } } - /** - * \brief is this operation complex - * - * Complex operations are typically doing many reads to calculate the output of a single pixel. - * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true. - */ - bool isComplex() const - { - return this->m_complex; - } - virtual bool isSetOperation() const { return false; @@ -433,16 +457,6 @@ class NodeOperation { return CompositorPriority::Low; } - /** - * \brief can this NodeOperation be scheduled on an OpenCLDevice - * \see WorkScheduler.schedule - * \see ExecutionGroup.addOperation - */ - bool isOpenCL() const - { - return this->m_openCL; - } - virtual bool isViewerOperation() const { return false; @@ -451,10 +465,6 @@ class NodeOperation { { return false; } - virtual bool isFileOutputOperation() const - { - return false; - } virtual bool isProxyOperation() const { return false; @@ -534,12 +544,12 @@ class NodeOperation { void setWidth(unsigned int width) { this->m_width = width; - this->m_isResolutionSet = true; + this->flags.is_resolution_set = true; } void setHeight(unsigned int height) { this->m_height = height; - this->m_isResolutionSet = true; + this->flags.is_resolution_set = true; } SocketReader *getInputSocketReader(unsigned int inputSocketindex); NodeOperation *getInputOperation(unsigned int inputSocketindex); @@ -557,15 +567,7 @@ class NodeOperation { */ void setComplex(bool complex) { - this->m_complex = complex; - } - - /** - * \brief set if this NodeOperation can be scheduled on a OpenCLDevice - */ - void setOpenCL(bool openCL) - { - this->m_openCL = openCL; + this->flags.complex = complex; } /** diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc index 44adb26a412..920622651b1 100644 --- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc +++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc @@ -536,7 +536,7 @@ void NodeOperationBuilder::add_complex_operation_buffers() */ blender::Vector complex_ops; for (NodeOperation *operation : m_operations) { - if (operation->isComplex()) { + if (operation->get_flags().complex) { complex_ops.append(operation); } } diff --git a/source/blender/compositor/intern/COM_SingleThreadedOperation.cc b/source/blender/compositor/intern/COM_SingleThreadedOperation.cc index d7341ff7fdd..c5e4c7ee9fd 100644 --- a/source/blender/compositor/intern/COM_SingleThreadedOperation.cc +++ b/source/blender/compositor/intern/COM_SingleThreadedOperation.cc @@ -23,7 +23,7 @@ namespace blender::compositor { SingleThreadedOperation::SingleThreadedOperation() { this->m_cachedInstance = nullptr; - setComplex(true); + flags.complex = true; } void SingleThreadedOperation::initExecution() diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cc b/source/blender/compositor/intern/COM_WorkScheduler.cc index 6a7de0a1c73..7224078a2c3 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cc +++ b/source/blender/compositor/intern/COM_WorkScheduler.cc @@ -144,7 +144,7 @@ static void opencl_start(CompositorContext &context) static bool opencl_schedule(WorkPackage *package) { - if (package->execution_group->isOpenCL() && g_work_scheduler.opencl.active) { + if (package->execution_group->get_flags().open_cl && g_work_scheduler.opencl.active) { BLI_thread_queue_push(g_work_scheduler.opencl.queue, package); return true; } diff --git a/source/blender/compositor/intern/COM_WorkScheduler.h b/source/blender/compositor/intern/COM_WorkScheduler.h index a8a76944939..758bd8feb26 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.h +++ b/source/blender/compositor/intern/COM_WorkScheduler.h @@ -33,7 +33,7 @@ struct WorkScheduler { /** * \brief schedule a chunk of a group to be calculated. * An execution group schedules a chunk in the WorkScheduler - * when ExecutionGroup.isOpenCL is set the work will be handled by a OpenCLDevice + * when ExecutionGroup.get_flags().open_cl is set the work will be handled by a OpenCLDevice * otherwise the work is scheduled for an CPUDevice * \see ExecutionGroup.execute * \param group: the execution group -- cgit v1.2.3