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_NodeOperation.h
Jeroen Bakker be1b5f82ce * optimized threading
* break out with glare node
 * Added OpenCL kernels compatible with AMD still need some testing.
2012-06-13 12:34:56 +00:00

287 lines
10 KiB
C++

/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_NodeOperation_h
#define _COM_NodeOperation_h
class NodeOperation;
#include "COM_Node.h"
#include <string>
#include <sstream>
#include "COM_MemoryBuffer.h"
#include "COM_MemoryProxy.h"
#include "COM_SocketReader.h"
#include "OCL_opencl.h"
#include "list"
#include "BLI_threads.h"
#include "BLI_math_color.h"
#include "BLI_math_vector.h"
class ReadBufferOperation;
/**
* @brief NodeOperation are contains calculation logic
*
* Subclasses needs to implement the execution method (defined in SocketReader) to implement logic.
* @ingroup Model
*/
class NodeOperation : public NodeBase, public SocketReader {
private:
/**
* @brief the index of the input socket that will be used to determine the resolution
*/
unsigned int 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 complex;
/**
* @brief can this operation be scheduled on an OpenCL device.
* @note Only applicable if complex is True
*/
bool openCL;
/**
* @brief mutex reference for very special node initializations
* @note only use when you really know what you are doing.
* this mutex is used to share data among chunks in the same operation
* @see TonemapOperation for an example of usage
* @see NodeOperation.initMutex initializes this mutex
* @see NodeOperation.deinitMutex deinitializes this mutex
* @see NodeOperation.getMutex retrieve a pointer to this mutex.
*/
ThreadMutex mutex;
/**
* @brief reference to the editing bNodeTree only used for break callback
*/
const bNodeTree *btree;
public:
/**
* @brief is this node an operation?
* This is true when the instance is of the subclass NodeOperation.
* @return [true:false]
* @see NodeBase
*/
const int isOperation() const {return true;}
/**
* @brief determine the resolution of this node
* @note this method will not set the resolution, this is the responsibility of the caller
* @param resolution the result of this operation
* @param preferredResolution the preferrable resolution as no resolution could be determined
*/
virtual void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]);
/**
* @brief isOutputOperation determines whether this operation is an output of the ExecutionSystem during rendering or editing.
*
* Default behaviour if not overriden, this operation will not be evaluated as being an output of the ExecutionSystem.
*
* @see ExecutionSystem
* @group check
* @param rendering [true false]
* true: rendering
* false: editing
*
* @return bool the result of this method
*/
virtual bool isOutputOperation(bool rendering) const {return false;}
/**
* isBufferOperation returns if this is an operation that work directly on buffers.
*
* there are only 2 implementation where this is true:
* @see ReadBufferOperation
* @see WriteBufferOperation
* for all other operations this will result in false.
*/
virtual int isBufferOperation() {return false;}
virtual int isSingleThreaded() {return false;}
void setbNodeTree(const bNodeTree * tree) {this->btree = tree;}
virtual void initExecution();
/**
* @brief when a chunk is executed by a CPUDevice, this method is called
* @ingroup execution
* @param rect the rectangle of the chunk (location and size)
* @param chunkNumber the chunkNumber to be calculated
* @param memoryBuffers all input MemoryBuffer's needed
*/
virtual void executeRegion(rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers) {}
/**
* @brief when a chunk is executed by an OpenCLDevice, this method is called
* @ingroup execution
* @note this method is only implemented in WriteBufferOperation
* @param context the OpenCL context
* @param program the OpenCL program containing all compositor kernels
* @param queue the OpenCL command queue of the device the chunk is executed on
* @param rect the rectangle of the chunk (location and size)
* @param chunkNumber the chunkNumber to be calculated
* @param memoryBuffers all input MemoryBuffer's needed
* @param outputBuffer the outputbuffer to write to
*/
virtual void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect,
unsigned int chunkNumber, MemoryBuffer** memoryBuffers, MemoryBuffer* outputBuffer) {}
/**
* @brief custom handle to add new tasks to the OpenCL command queue in order to execute a chunk on an GPUDevice
* @ingroup execution
* @param context the OpenCL context
* @param program the OpenCL program containing all compositor kernels
* @param queue the OpenCL command queue of the device the chunk is executed on
* @param outputMemoryBuffer the allocated memory buffer in main CPU memory
* @param clOutputBuffer the allocated memory buffer in OpenCLDevice memory
* @param inputMemoryBuffers all input MemoryBuffer's needed
* @param clMemToCleanUp all created cl_mem references must be added to this list. Framework will clean this after execution
* @param clKernelsToCleanUp all created cl_kernel references must be added to this list. Framework will clean this after execution
*/
virtual void executeOpenCL(cl_context context,cl_program program, cl_command_queue queue, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer** inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp) {}
virtual void deinitExecution();
bool isResolutionSet() {
return this->width != 0 && height != 0;
}
/**
* @brief set the resolution
* @param resolution the resolution to set
*/
void setResolution(unsigned int resolution[]) {
if (!isResolutionSet()) {
this->width = resolution[0];
this->height = resolution[1];
}
}
void getConnectedInputSockets(vector<InputSocket*> *sockets);
/**
* @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.
*/
const bool isComplex() const {return this->complex;}
virtual const bool isSetOperation() const {return false;}
/**
* @brief is this operation of type ReadBufferOperation
* @return [true:false]
* @see ReadBufferOperation
*/
virtual const bool isReadBufferOperation() const {return false;}
/**
* @brief is this operation of type WriteBufferOperation
* @return [true:false]
* @see WriteBufferOperation
*/
virtual const bool isWriteBufferOperation() const {return false;}
/**
* @brief is this operation the active viewer output
* user can select an ViewerNode to be active (the result of this node will be drawn on the backdrop)
* @return [true:false]
* @see BaseViewerOperation
*/
virtual const bool isActiveViewerOutput() const {return false;}
virtual bool determineDependingAreaOfInterest(rcti * input, ReadBufferOperation *readOperation, rcti *output);
/**
* @brief set the index of the input socket that will determine the resolution of this operation
* @param index the index to set
*/
void setResolutionInputSocketIndex(unsigned int index);
/**
* @brief get the render priority of this node.
* @note only applicable for output operations like ViewerOperation
* @return CompositorPriority
*/
virtual const CompositorPriority getRenderPriority() const {return COM_PRIORITY_LOW;}
/**
* @brief can this NodeOperation be scheduled on an OpenCLDevice
* @see WorkScheduler.schedule
* @see ExecutionGroup.addOperation
*/
bool isOpenCL() { return this->openCL; }
virtual bool isViewerOperation() {return false;}
virtual bool isPreviewOperation() {return false;}
inline bool isBreaked() {
return btree->test_break(btree->tbh);
}
protected:
NodeOperation();
void setWidth(unsigned int width) {this->width = width;}
void setHeight(unsigned int height) {this->height = height;}
SocketReader *getInputSocketReader(unsigned int inputSocketindex);
NodeOperation *getInputOperation(unsigned int inputSocketindex);
void deinitMutex();
void initMutex();
void lockMutex();
void unlockMutex();
/**
* @brief set whether this operation is 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.
*/
void setComplex(bool complex) {this->complex = complex;}
/**
* @brief set if this NodeOperation can be scheduled on a OpenCLDevice
*/
void setOpenCL(bool openCL) {this->openCL = openCL;}
static cl_mem COM_clAttachMemoryBufferToKernelParameter(cl_context context, cl_kernel kernel, int parameterIndex, int offsetIndex, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, SocketReader* reader);
static void COM_clAttachMemoryBufferOffsetToKernelParameter(cl_kernel kernel, int offsetIndex, MemoryBuffer *memoryBuffers);
static void COM_clAttachOutputMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, cl_mem clOutputMemoryBuffer);
void COM_clAttachSizeToKernelParameter(cl_kernel kernel, int offsetIndex);
static void COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer* outputMemoryBuffer);
void COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer *outputMemoryBuffer, int offsetIndex);
cl_kernel COM_clCreateKernel(cl_program program, const char* kernelname, list<cl_kernel> *clKernelsToCleanUp);
};
#endif