diff options
Diffstat (limited to 'source/blender/compositor/intern/COM_ExecutionGroup.h')
-rw-r--r-- | source/blender/compositor/intern/COM_ExecutionGroup.h | 750 |
1 files changed, 385 insertions, 365 deletions
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index c7a371b226a..ff9ac5d0582 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -39,18 +39,18 @@ class Device; * \ingroup Execution */ typedef enum ChunkExecutionState { - /** - * \brief chunk is not yet scheduled - */ - COM_ES_NOT_SCHEDULED = 0, - /** - * \brief chunk is scheduled, but not yet executed - */ - COM_ES_SCHEDULED = 1, - /** - * \brief chunk is executed. - */ - COM_ES_EXECUTED = 2, + /** + * \brief chunk is not yet scheduled + */ + COM_ES_NOT_SCHEDULED = 0, + /** + * \brief chunk is scheduled, but not yet executed + */ + COM_ES_SCHEDULED = 1, + /** + * \brief chunk is executed. + */ + COM_ES_EXECUTED = 2, } ChunkExecutionState; /** @@ -59,361 +59,381 @@ typedef enum ChunkExecutionState { * \ingroup Execution */ class ExecutionGroup { -public: - typedef std::vector<NodeOperation*> Operations; - -private: - // fields - - /** - * \brief list of operations in this ExecutionGroup - */ - Operations 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) - */ - int m_isOutput; - - /** - * \brief Width of the output - */ - unsigned int m_width; - - /** - * \brief Height of the output - */ - unsigned int m_height; - - /** - * \brief size of a single chunk, being Width or of height - * a chunk is always a square, except at the edges of the MemoryBuffer - */ - unsigned int m_chunkSize; - - /** - * \brief number of chunks in the x-axis - */ - unsigned int m_numberOfXChunks; - - /** - * \brief number of chunks in the y-axis - */ - unsigned int m_numberOfYChunks; - - /** - * \brief total number of chunks - */ - unsigned int m_numberOfChunks; - - /** - * \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. - */ - unsigned int m_cachedMaxReadBufferOffset; - - /** - * \brief a cached vector of all read operations in the execution group. - */ - Operations m_cachedReadOperations; - - /** - * \brief reference to the original bNodeTree, this field is only set for the 'top' execution group. - * \note can only be used to call the callbacks for progress, status and break - */ - const bNodeTree *m_bTree; - - /** - * \brief total number of chunks that have been calculated for this ExecutionGroup - */ - unsigned int m_chunksFinished; - - /** - * \brief the chunkExecutionStates holds per chunk the execution state. this state can be - * - COM_ES_NOT_SCHEDULED: not scheduled - * - COM_ES_SCHEDULED: scheduled - * - COM_ES_EXECUTED: executed - */ - ChunkExecutionState *m_chunkExecutionStates; - - /** - * \brief indicator when this ExecutionGroup has valid Operations in its vector for Execution - * \note When building the ExecutionGroup Operations are added via recursion. First a WriteBufferOperations is added, then the - * \note Operation containing the settings that is important for the ExecutiongGroup is added, - * \note When this occurs, these settings are copied over from the node to the ExecutionGroup - * \note and the Initialized flag is set to true. - * \see complex - * \see openCL - */ - bool m_initialized; - - /** - * \brief denotes boundary for border compositing - * \note measured in pixel space - */ - rcti m_viewerBorder; - - /** - * \brief start time of execution - */ - double m_executionStartTime; - - // methods - /** - * \brief check whether parameter operation can be added to the execution group - * \param operation: the operation to be added - */ - bool canContainOperation(NodeOperation *operation); - - /** - * \brief calculate the actual chunk size of this execution group. - * \note A chunk size is an unsigned int that is both the height and width of a chunk. - * \note The chunk size will not be stored in the chunkSize field. This needs to be done - * \note by the calling method. - */ - unsigned int determineChunkSize(); - - - /** - * \brief Determine the rect (minx, maxx, miny, maxy) of a chunk at a position. - * \note Only gives useful results ater the determination of the chunksize - * \see determineChunkSize() - */ - void determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk) const; - - /** - * \brief determine the number of chunks, based on the chunkSize, width and height. - * \note The result are stored in the fields numberOfChunks, numberOfXChunks, numberOfYChunks - */ - void determineNumberOfChunks(); - - /** - * \brief try to schedule a specific chunk. - * \note scheduling succeeds when all input requirements are met and the chunks hasn't been scheduled yet. - * \param graph: - * \param xChunk: - * \param yChunk: - * \return [true:false] - * true: package(s) are scheduled - * false: scheduling is deferred (depending workpackages are scheduled) - */ - bool scheduleChunkWhenPossible(ExecutionSystem *graph, int xChunk, int yChunk); - - /** - * \brief try to schedule a specific area. - * \note Check if a certain area is available, when not available this are will be checked. - * \note This method is called from other ExecutionGroup's. - * \param graph: - * \param rect: - * \return [true:false] - * true: package(s) are scheduled - * false: scheduling is deferred (depending workpackages are scheduled) - */ - bool scheduleAreaWhenPossible(ExecutionSystem *graph, rcti *rect); - - /** - * \brief add a chunk to the WorkScheduler. - * \param chunknumber: - */ - bool scheduleChunk(unsigned int chunkNumber); - - /** - * \brief determine the area of interest of a certain input area - * \note This method only evaluates a single ReadBufferOperation - * \param input: the input area - * \param readOperation: The ReadBufferOperation where the area needs to be evaluated - * \param output: the area needed of the ReadBufferOperation. Result - */ - void determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - - -public: - // constructors - ExecutionGroup(); - - // methods - /** - * \brief add an operation to this ExecutionGroup - * \note this method will add input of the operations recursively - * \note this method can create multiple ExecutionGroup's - * \param system: - * \param operation: - * \return True if the operation was successfully added - */ - 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 - */ - int isOutputExecutionGroup() const { return this->m_isOutput; } - - /** - * \brief set whether this ExecutionGroup is an output - * \param isOutput: - */ - void setOutputExecutionGroup(int isOutput) { this->m_isOutput = isOutput; } - - /** - * \brief determine the resolution of this ExecutionGroup - * \param resolution: - */ - void determineResolution(unsigned int resolution[2]); - - /** - * \brief set the resolution of this executiongroup - * \param resolution: - */ - void setResolution(unsigned int resolution[2]) { this->m_width = resolution[0]; this->m_height = resolution[1]; } - - /** - * \brief get the width of this execution group - */ - unsigned int getWidth() const { return m_width; } - - /** - * \brief get the height of this execution group - */ - unsigned int getHeight() const { 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 - */ - NodeOperation *getOutputOperation() const; - - /** - * \brief compose multiple chunks into a single chunk - * \return Memorybuffer *consolidated chunk - */ - MemoryBuffer *constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy, rcti *output); - - /** - * \brief initExecution is called just before the execution of the whole graph will be done. - * \note The implementation will calculate the chunkSize of this execution group. - */ - void initExecution(); - - /** - * \brief get all inputbuffers needed to calculate an chunk - * \note all inputbuffers must be executed - * \param chunkNumber: the chunk to be calculated - * \return (MemoryBuffer **) the inputbuffers - */ - MemoryBuffer **getInputBuffersCPU(); - - /** - * \brief get all inputbuffers needed to calculate an chunk - * \note all inputbuffers must be executed - * \param chunkNumber: the chunk to be calculated - * \return (MemoryBuffer **) the inputbuffers - */ - MemoryBuffer **getInputBuffersOpenCL(int chunkNumber); - - /** - * \brief allocate the outputbuffer of a chunk - * \param chunkNumber: the number of the chunk in the ExecutionGroup - * \param rect: the rect of that chunk - * \see determineChunkRect - */ - MemoryBuffer *allocateOutputBuffer(int chunkNumber, rcti *rect); - - /** - * \brief after a chunk is executed the needed resources can be freed or unlocked. - * \param chunknumber: - * \param memorybuffers: - */ - void finalizeChunkExecution(int chunkNumber, MemoryBuffer **memoryBuffers); - - /** - * \brief deinitExecution is called just after execution the whole graph. - * \note It will release all needed resources - */ - void deinitExecution(); - - - /** - * \brief schedule an ExecutionGroup - * \note this method will return when all chunks have been calculated, or the execution has breaked (by user) - * - * first the order of the chunks will be determined. This is determined by finding the ViewerOperation and get the relevant information from it. - * - ChunkOrdering - * - CenterX - * - CenterY - * - * After determining the order of the chunks the chunks will be scheduled - * - * \see ViewerOperation - * \param system: - */ - void execute(ExecutionSystem *system); - - /** - * \brief this method determines the MemoryProxy's where this execution group depends on. - * \note After this method determineDependingAreaOfInterest can be called to determine - * \note the area of the MemoryProxy.creator that has to be executed. - * \param memoryProxies: result - */ - void determineDependingMemoryProxies(vector<MemoryProxy *> *memoryProxies); - - /** - * \brief Determine the rect (minx, maxx, miny, maxy) of a chunk. - * \note Only gives useful results ater the determination of the chunksize - * \see determineChunkSize() - */ - 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; } - - /** - * \brief get the Render priority of this ExecutionGroup - * \see ExecutionSystem.execute - */ - CompositorPriority getRenderPriotrity(); - - /** - * \brief set border for viewer operation - * \note all the coordinates are assumed to be in normalized space - */ - void setViewerBorder(float xmin, float xmax, float ymin, float ymax); - - void setRenderBorder(float xmin, float xmax, float ymin, float ymax); - - /* allow the DebugInfo class to look at internals */ - friend class DebugInfo; + public: + typedef std::vector<NodeOperation *> Operations; + + private: + // fields + + /** + * \brief list of operations in this ExecutionGroup + */ + Operations 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) + */ + int m_isOutput; + + /** + * \brief Width of the output + */ + unsigned int m_width; + + /** + * \brief Height of the output + */ + unsigned int m_height; + + /** + * \brief size of a single chunk, being Width or of height + * a chunk is always a square, except at the edges of the MemoryBuffer + */ + unsigned int m_chunkSize; + + /** + * \brief number of chunks in the x-axis + */ + unsigned int m_numberOfXChunks; + + /** + * \brief number of chunks in the y-axis + */ + unsigned int m_numberOfYChunks; + + /** + * \brief total number of chunks + */ + unsigned int m_numberOfChunks; + + /** + * \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. + */ + unsigned int m_cachedMaxReadBufferOffset; + + /** + * \brief a cached vector of all read operations in the execution group. + */ + Operations m_cachedReadOperations; + + /** + * \brief reference to the original bNodeTree, this field is only set for the 'top' execution group. + * \note can only be used to call the callbacks for progress, status and break + */ + const bNodeTree *m_bTree; + + /** + * \brief total number of chunks that have been calculated for this ExecutionGroup + */ + unsigned int m_chunksFinished; + + /** + * \brief the chunkExecutionStates holds per chunk the execution state. this state can be + * - COM_ES_NOT_SCHEDULED: not scheduled + * - COM_ES_SCHEDULED: scheduled + * - COM_ES_EXECUTED: executed + */ + ChunkExecutionState *m_chunkExecutionStates; + + /** + * \brief indicator when this ExecutionGroup has valid Operations in its vector for Execution + * \note When building the ExecutionGroup Operations are added via recursion. First a WriteBufferOperations is added, then the + * \note Operation containing the settings that is important for the ExecutiongGroup is added, + * \note When this occurs, these settings are copied over from the node to the ExecutionGroup + * \note and the Initialized flag is set to true. + * \see complex + * \see openCL + */ + bool m_initialized; + + /** + * \brief denotes boundary for border compositing + * \note measured in pixel space + */ + rcti m_viewerBorder; + + /** + * \brief start time of execution + */ + double m_executionStartTime; + + // methods + /** + * \brief check whether parameter operation can be added to the execution group + * \param operation: the operation to be added + */ + bool canContainOperation(NodeOperation *operation); + + /** + * \brief calculate the actual chunk size of this execution group. + * \note A chunk size is an unsigned int that is both the height and width of a chunk. + * \note The chunk size will not be stored in the chunkSize field. This needs to be done + * \note by the calling method. + */ + unsigned int determineChunkSize(); + + /** + * \brief Determine the rect (minx, maxx, miny, maxy) of a chunk at a position. + * \note Only gives useful results ater the determination of the chunksize + * \see determineChunkSize() + */ + void determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk) const; + + /** + * \brief determine the number of chunks, based on the chunkSize, width and height. + * \note The result are stored in the fields numberOfChunks, numberOfXChunks, numberOfYChunks + */ + void determineNumberOfChunks(); + + /** + * \brief try to schedule a specific chunk. + * \note scheduling succeeds when all input requirements are met and the chunks hasn't been scheduled yet. + * \param graph: + * \param xChunk: + * \param yChunk: + * \return [true:false] + * true: package(s) are scheduled + * false: scheduling is deferred (depending workpackages are scheduled) + */ + bool scheduleChunkWhenPossible(ExecutionSystem *graph, int xChunk, int yChunk); + + /** + * \brief try to schedule a specific area. + * \note Check if a certain area is available, when not available this are will be checked. + * \note This method is called from other ExecutionGroup's. + * \param graph: + * \param rect: + * \return [true:false] + * true: package(s) are scheduled + * false: scheduling is deferred (depending workpackages are scheduled) + */ + bool scheduleAreaWhenPossible(ExecutionSystem *graph, rcti *rect); + + /** + * \brief add a chunk to the WorkScheduler. + * \param chunknumber: + */ + bool scheduleChunk(unsigned int chunkNumber); + + /** + * \brief determine the area of interest of a certain input area + * \note This method only evaluates a single ReadBufferOperation + * \param input: the input area + * \param readOperation: The ReadBufferOperation where the area needs to be evaluated + * \param output: the area needed of the ReadBufferOperation. Result + */ + void determineDependingAreaOfInterest(rcti *input, + ReadBufferOperation *readOperation, + rcti *output); + + public: + // constructors + ExecutionGroup(); + + // methods + /** + * \brief add an operation to this ExecutionGroup + * \note this method will add input of the operations recursively + * \note this method can create multiple ExecutionGroup's + * \param system: + * \param operation: + * \return True if the operation was successfully added + */ + 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 + */ + int isOutputExecutionGroup() const + { + return this->m_isOutput; + } + + /** + * \brief set whether this ExecutionGroup is an output + * \param isOutput: + */ + void setOutputExecutionGroup(int isOutput) + { + this->m_isOutput = isOutput; + } + + /** + * \brief determine the resolution of this ExecutionGroup + * \param resolution: + */ + void determineResolution(unsigned int resolution[2]); + + /** + * \brief set the resolution of this executiongroup + * \param resolution: + */ + void setResolution(unsigned int resolution[2]) + { + this->m_width = resolution[0]; + this->m_height = resolution[1]; + } + + /** + * \brief get the width of this execution group + */ + unsigned int getWidth() const + { + return m_width; + } + + /** + * \brief get the height of this execution group + */ + unsigned int getHeight() const + { + 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 + */ + NodeOperation *getOutputOperation() const; + + /** + * \brief compose multiple chunks into a single chunk + * \return Memorybuffer *consolidated chunk + */ + MemoryBuffer *constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy, rcti *output); + + /** + * \brief initExecution is called just before the execution of the whole graph will be done. + * \note The implementation will calculate the chunkSize of this execution group. + */ + void initExecution(); + + /** + * \brief get all inputbuffers needed to calculate an chunk + * \note all inputbuffers must be executed + * \param chunkNumber: the chunk to be calculated + * \return (MemoryBuffer **) the inputbuffers + */ + MemoryBuffer **getInputBuffersCPU(); + + /** + * \brief get all inputbuffers needed to calculate an chunk + * \note all inputbuffers must be executed + * \param chunkNumber: the chunk to be calculated + * \return (MemoryBuffer **) the inputbuffers + */ + MemoryBuffer **getInputBuffersOpenCL(int chunkNumber); + + /** + * \brief allocate the outputbuffer of a chunk + * \param chunkNumber: the number of the chunk in the ExecutionGroup + * \param rect: the rect of that chunk + * \see determineChunkRect + */ + MemoryBuffer *allocateOutputBuffer(int chunkNumber, rcti *rect); + + /** + * \brief after a chunk is executed the needed resources can be freed or unlocked. + * \param chunknumber: + * \param memorybuffers: + */ + void finalizeChunkExecution(int chunkNumber, MemoryBuffer **memoryBuffers); + + /** + * \brief deinitExecution is called just after execution the whole graph. + * \note It will release all needed resources + */ + void deinitExecution(); + + /** + * \brief schedule an ExecutionGroup + * \note this method will return when all chunks have been calculated, or the execution has breaked (by user) + * + * first the order of the chunks will be determined. This is determined by finding the ViewerOperation and get the relevant information from it. + * - ChunkOrdering + * - CenterX + * - CenterY + * + * After determining the order of the chunks the chunks will be scheduled + * + * \see ViewerOperation + * \param system: + */ + void execute(ExecutionSystem *system); + + /** + * \brief this method determines the MemoryProxy's where this execution group depends on. + * \note After this method determineDependingAreaOfInterest can be called to determine + * \note the area of the MemoryProxy.creator that has to be executed. + * \param memoryProxies: result + */ + void determineDependingMemoryProxies(vector<MemoryProxy *> *memoryProxies); + + /** + * \brief Determine the rect (minx, maxx, miny, maxy) of a chunk. + * \note Only gives useful results ater the determination of the chunksize + * \see determineChunkSize() + */ + 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; + } + + /** + * \brief get the Render priority of this ExecutionGroup + * \see ExecutionSystem.execute + */ + CompositorPriority getRenderPriotrity(); + + /** + * \brief set border for viewer operation + * \note all the coordinates are assumed to be in normalized space + */ + void setViewerBorder(float xmin, float xmax, float ymin, float ymax); + + void setRenderBorder(float xmin, float xmax, float ymin, float ymax); + + /* allow the DebugInfo class to look at internals */ + friend class DebugInfo; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionGroup") + MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionGroup") #endif }; |