diff options
Diffstat (limited to 'source/blender/compositor')
187 files changed, 2102 insertions, 1101 deletions
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index 4bcdd4d9e34..972db6b71d2 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -41,6 +41,7 @@ set(INC ../render/intern/include ../../../extern/clew/include ../../../intern/guardedalloc + ../../../intern/atomic ) set(INC_SYS @@ -90,8 +91,6 @@ set(SRC intern/COM_OpenCLDevice.h intern/COM_CompositorContext.cpp intern/COM_CompositorContext.h - intern/COM_ChannelInfo.cpp - intern/COM_ChannelInfo.h intern/COM_SingleThreadedOperation.cpp intern/COM_SingleThreadedOperation.h intern/COM_Debug.cpp @@ -121,6 +120,8 @@ set(SRC nodes/COM_TimeNode.h nodes/COM_SwitchNode.cpp nodes/COM_SwitchNode.h + nodes/COM_SwitchViewNode.cpp + nodes/COM_SwitchViewNode.h nodes/COM_MovieClipNode.cpp nodes/COM_MovieClipNode.h nodes/COM_OutputFileNode.cpp @@ -372,6 +373,8 @@ set(SRC operations/COM_CompositorOperation.cpp operations/COM_OutputFileOperation.h operations/COM_OutputFileOperation.cpp + operations/COM_OutputFileMultiViewOperation.h + operations/COM_OutputFileMultiViewOperation.cpp operations/COM_ViewerOperation.h operations/COM_ViewerOperation.cpp operations/COM_PreviewOperation.h @@ -537,9 +540,19 @@ set(SRC list(APPEND INC ${CMAKE_CURRENT_BINARY_DIR}/operations ) + +if(WITH_COMPOSITOR_WERROR) + ADD_CHECK_C_COMPILER_FLAG(CMAKE_C_FLAGS C_WERROR -Werror) + ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS C_WERROR -Werror) +endif() + data_to_c(${CMAKE_CURRENT_SOURCE_DIR}/operations/COM_OpenCLKernels.cl ${CMAKE_CURRENT_BINARY_DIR}/operations/COM_OpenCLKernels.cl.h SRC) add_definitions(-DCL_USE_DEPRECATED_OPENCL_1_1_APIS) +if(WITH_CYCLES AND WITH_CYCLES_DEBUG) + add_definitions(-DWITH_CYCLES_DEBUG) +endif() + blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h index 9b22444cf7f..a5d7704a708 100644 --- a/source/blender/compositor/COM_compositor.h +++ b/source/blender/compositor/COM_compositor.h @@ -38,7 +38,7 @@ extern "C" { * @defgroup Node All nodes of the compositor * @defgroup Operation All operations of the compositor * - * @mainpage Introduction of the Blender Compositor + * @page Introduction of the Blender Compositor * * @section bcomp Blender compositor * This project redesigns the internals of Blender's compositor. The project has been executed in 2011 by At Mind. @@ -316,7 +316,8 @@ extern "C" { * generation in display space */ void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rendering, - const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings); + const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings, + const char *viewName); /** * @brief Deinitialize the compositor caches and allocated memory. diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h index b60fffc6a22..9936914d3d8 100644 --- a/source/blender/compositor/COM_defines.h +++ b/source/blender/compositor/COM_defines.h @@ -105,7 +105,9 @@ typedef enum OrderOfChunks { #define COM_RULE_OF_THIRDS_DIVIDER 100.0f -#define COM_NUMBER_OF_CHANNELS 4 +#define COM_NUM_CHANNELS_VALUE 1 +#define COM_NUM_CHANNELS_VECTOR 3 +#define COM_NUM_CHANNELS_COLOR 4 #define COM_BLUR_BOKEH_PIXELS 512 diff --git a/source/blender/compositor/SConscript b/source/blender/compositor/SConscript index eab40873f64..b3fe494a25c 100644 --- a/source/blender/compositor/SConscript +++ b/source/blender/compositor/SConscript @@ -50,6 +50,7 @@ incs = [ '../render/intern/include', '../windowmanager', '../../../intern/guardedalloc', + '../../../intern/atomic', # data files env['DATA_HEADERS'], @@ -58,6 +59,9 @@ incs = [ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs.append(env['BF_PTHREADS_INC']) +if env['WITH_BF_CYCLES'] and env['WITH_BF_CYCLES_DEBUG']: + defs.append('WITH_CYCLES_DEBUG') + if False: # gives link errors 'win' in env['OURPLATFORM']: # split into 3 modules to work around command length limit on Windows env.BlenderLib('bf_composite_intern', sources_intern, incs, defines=defs, libtype=['core'], priority=[166]) diff --git a/source/blender/compositor/intern/COM_ChannelInfo.h b/source/blender/compositor/intern/COM_ChannelInfo.h deleted file mode 100644 index ec78e7e1cb1..00000000000 --- a/source/blender/compositor/intern/COM_ChannelInfo.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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_ChannelInfo_h -#define _COM_ChannelInfo_h - -#include <vector> -#include "BKE_text.h" -#include <string> -#include "DNA_node_types.h" -#include "BLI_rect.h" - -using namespace std; - -/** - * @brief List of possible channel types - * @ingroup Model - */ -typedef enum ChannelType { - COM_CT_ColorComponent /** @brief this channel is contains color information. Specific used is determined by channelnumber, and in the future color space */, - COM_CT_Alpha /** @brief this channel is contains transparency value */, - COM_CT_Value /** @brief this channel is contains a value */, - COM_CT_X /** @brief this channel is contains a X value */, - COM_CT_Y /** @brief this channel is contains a Y value */, - COM_CT_Z /** @brief this channel is contains a Z value */, - COM_CT_W /** @brief this channel is contains a W value */, - COM_CT_UNUSED /** @brief this channel is unused */ -} ChannelType; - -/** - * @brief ChannelInfo holds information about a channel. - * - * Channels are transported from node to node via a NodeLink. - * ChannelInfo holds specific setting of these channels in order that the to-node of the link - * Can handle specific logic per channel setting. - * - * @note currently this is not used, but a future place to implement color spacing and other things. - * @ingroup Model - */ -class ChannelInfo { -private: - /** - * @brief the channel number, in the link. [0-3] - */ - int m_number; - - /** - * @brief type of channel - */ - ChannelType m_type; - - /** - * @brieg Is this value in this channel premultiplied with its alpha - * @note only valid if type = ColorComponent; - */ - bool m_premultiplied; - -// /** -// * Color space of this value. -// * only valid when type = ColorComponent; -// */ -// string colorspacename; - -public: - /** - * @brief creates a new ChannelInfo and set default values - */ - ChannelInfo(); - - /** - * @brief set the index of this channel in the NodeLink - */ - void setNumber(const int number) { this->m_number = number; } - - /** - * @brief get the index of this channel in the NodeLink - */ - const int getNumber() const { return this->m_number; } - - /** - * @brief set the type of channel - */ - void setType(const ChannelType type) { this->m_type = type; } - - /** - * @brief get the type of channel - */ - const ChannelType getType() const { return this->m_type; } - - /** - * @brief set the premultiplicatioin of this channel - */ - void setPremultiplied(const bool premultiplied) { this->m_premultiplied = premultiplied; } - - /** - * @brief is this channel premultiplied - */ - const bool isPremultiplied() const { return this->m_premultiplied; } -}; - - -#endif diff --git a/source/blender/compositor/intern/COM_CompositorContext.h b/source/blender/compositor/intern/COM_CompositorContext.h index a398ae937a3..d7ec653f480 100644 --- a/source/blender/compositor/intern/COM_CompositorContext.h +++ b/source/blender/compositor/intern/COM_CompositorContext.h @@ -87,6 +87,11 @@ private: const ColorManagedViewSettings *m_viewSettings; const ColorManagedDisplaySettings *m_displaySettings; + /** + * @brief active rendering view name + */ + const char *m_viewName; + public: /** * @brief constructor initializes the context with default values. @@ -180,12 +185,22 @@ public: * @brief set has this system active openclDevices? */ void setHasActiveOpenCLDevices(bool hasAvtiveOpenCLDevices) { this->m_hasActiveOpenCLDevices = hasAvtiveOpenCLDevices; } - + + /** + * @brief get the active rendering view + */ + const char *getViewName() const { return this->m_viewName; } + + /** + * @brief set the active rendering view + */ + void setViewName(const char *viewName) { this->m_viewName = viewName; } + int getChunksize() const { return this->getbNodeTree()->chunksize; } void setFastCalculation(bool fastCalculation) {this->m_fastCalculation = fastCalculation;} bool isFastCalculation() const { return this->m_fastCalculation; } - bool isGroupnodeBufferEnabled() const { return this->getbNodeTree()->flag & NTREE_COM_GROUPNODE_BUFFER; } + bool isGroupnodeBufferEnabled() const { return (this->getbNodeTree()->flag & NTREE_COM_GROUPNODE_BUFFER) != 0; } }; diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 99f66bcb5b4..9fa59be4a1c 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -101,6 +101,7 @@ extern "C" { #include "COM_Stabilize2dNode.h" #include "COM_SunBeamsNode.h" #include "COM_SwitchNode.h" +#include "COM_SwitchViewNode.h" #include "COM_TextureNode.h" #include "COM_TimeNode.h" #include "COM_TonemapNode.h" @@ -136,6 +137,10 @@ Node *Converter::convert(bNode *b_node) { Node *node = NULL; + /* ignore undefined nodes with missing or invalid node data */ + if (!nodeIsRegistered(b_node)) + return NULL; + switch (b_node->type) { case CMP_NODE_COMPOSITE: node = new CompositorNode(b_node); @@ -328,6 +333,9 @@ Node *Converter::convert(bNode *b_node) case CMP_NODE_SWITCH: node = new SwitchNode(b_node); break; + case CMP_NODE_SWITCH_VIEW: + node = new SwitchViewNode(b_node); + break; case CMP_NODE_GLARE: node = new GlareNode(b_node); break; diff --git a/source/blender/compositor/intern/COM_Debug.cpp b/source/blender/compositor/intern/COM_Debug.cpp index 470f8fd2ef7..a7b464cde29 100644 --- a/source/blender/compositor/intern/COM_Debug.cpp +++ b/source/blender/compositor/intern/COM_Debug.cpp @@ -32,6 +32,7 @@ extern "C" { #include "BLI_path_util.h" #include "BLI_string.h" #include "DNA_node_types.h" +#include "BKE_appdir.h" #include "BKE_node.h" } @@ -212,7 +213,7 @@ int DebugInfo::graphviz_legend_color(const char *name, const char *color, char * return len; } -int DebugInfo::graphviz_legend_line(const char *name, const char *color, const char *style, char *str, int maxlen) +int DebugInfo::graphviz_legend_line(const char * /*name*/, const char * /*color*/, const char * /*style*/, char *str, int maxlen) { /* XXX TODO */ int len = 0; @@ -220,7 +221,7 @@ int DebugInfo::graphviz_legend_line(const char *name, const char *color, const c return len; } -int DebugInfo::graphviz_legend_group(const char *name, const char *color, const char *style, char *str, int maxlen) +int DebugInfo::graphviz_legend_group(const char *name, const char *color, const char * /*style*/, char *str, int maxlen) { int len = 0; len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "<TR><TD>%s</TD><TD CELLPADDING=\"4\"><TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\"><TR><TD BGCOLOR=\"%s\"></TD></TR></TABLE></TD></TR>\r\n", name, color); @@ -355,7 +356,7 @@ bool DebugInfo::graphviz_system(const ExecutionSystem *system, char *str, int ma std::string color; switch (from->getDataType()) { case COM_DT_VALUE: - color = "grey"; + color = "gray"; break; case COM_DT_VECTOR: color = "blue"; @@ -398,7 +399,7 @@ void DebugInfo::graphviz(const ExecutionSystem *system) char filename[FILE_MAX]; BLI_snprintf(basename, sizeof(basename), "compositor_%d.dot", m_file_index); - BLI_join_dirfile(filename, sizeof(filename), BLI_temp_dir_session(), basename); + BLI_join_dirfile(filename, sizeof(filename), BKE_tempdir_session(), basename); ++m_file_index; FILE *fp = BLI_fopen(filename, "wb"); diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index 366c97b50c6..5cb757d7dcb 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -25,12 +25,13 @@ #include <sstream> #include <stdlib.h> +#include "atomic_ops.h" + #include "COM_ExecutionGroup.h" #include "COM_defines.h" #include "COM_ExecutionSystem.h" #include "COM_ReadBufferOperation.h" #include "COM_WriteBufferOperation.h" -#include "COM_ReadBufferOperation.h" #include "COM_WorkScheduler.h" #include "COM_ViewerOperation.h" #include "COM_ChunkOrder.h" @@ -238,7 +239,7 @@ void ExecutionGroup::execute(ExecutionSystem *graph) chunkOrders[index].determineDistance(hotspots, 1); } - sort(&chunkOrders[0], &chunkOrders[this->m_numberOfChunks - 1]); + std::sort(&chunkOrders[0], &chunkOrders[this->m_numberOfChunks - 1]); for (index = 0; index < this->m_numberOfChunks; index++) { chunkOrder[index] = chunkOrders[index].getChunkNumber(); } @@ -277,7 +278,7 @@ void ExecutionGroup::execute(ExecutionSystem *graph) chunkOrders[index].determineDistance(hotspots, 9); } - sort(&chunkOrders[0], &chunkOrders[this->m_numberOfChunks]); + std::sort(&chunkOrders[0], &chunkOrders[this->m_numberOfChunks]); for (index = 0; index < this->m_numberOfChunks; index++) { chunkOrder[index] = chunkOrders[index].getChunkNumber(); @@ -377,41 +378,12 @@ MemoryBuffer *ExecutionGroup::constructConsolidatedMemoryBuffer(MemoryProxy *mem return result; } -void ExecutionGroup::printBackgroundStats(void) -{ - uintptr_t mem_in_use, mmap_in_use, peak_memory; - float megs_used_memory, mmap_used_memory, megs_peak_memory; - double execution_time; - char timestr[64]; - - execution_time = PIL_check_seconds_timer() - this->m_executionStartTime; - - mem_in_use = MEM_get_memory_in_use(); - mmap_in_use = MEM_get_mapped_memory_in_use(); - peak_memory = MEM_get_peak_memory(); - - megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0); - mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0); - megs_peak_memory = (peak_memory) / (1024.0 * 1024.0); - - fprintf(stdout, "Mem:%.2fM (%.2fM, Peak %.2fM) ", - megs_used_memory, mmap_used_memory, megs_peak_memory); - - BLI_timestr(execution_time, timestr, sizeof(timestr)); - printf("| Elapsed %s ", timestr); - printf("| Tree %s, Tile %u-%u ", this->m_bTree->id.name + 2, - this->m_chunksFinished, this->m_numberOfChunks); - - fputc('\n', stdout); - fflush(stdout); -} - void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer **memoryBuffers) { if (this->m_chunkExecutionStates[chunkNumber] == COM_ES_SCHEDULED) this->m_chunkExecutionStates[chunkNumber] = COM_ES_EXECUTED; - this->m_chunksFinished++; + atomic_add_u(&this->m_chunksFinished, 1); if (memoryBuffers) { for (unsigned int index = 0; index < this->m_cachedMaxReadBufferOffset; index++) { MemoryBuffer *buffer = memoryBuffers[index]; @@ -430,8 +402,11 @@ void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer **memo progress /= this->m_numberOfChunks; this->m_bTree->progress(this->m_bTree->prh, progress); - if (G.background) - printBackgroundStats(); + char buf[128]; + BLI_snprintf(buf, sizeof(buf), "Compositing | Tile %u-%u", + this->m_chunksFinished, + this->m_numberOfChunks); + this->m_bTree->stats_draw(this->m_bTree->sdh, buf); } } @@ -459,7 +434,8 @@ void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int chunkNumb determineChunkRect(rect, xChunk, yChunk); } -MemoryBuffer *ExecutionGroup::allocateOutputBuffer(int chunkNumber, rcti *rect) +MemoryBuffer *ExecutionGroup::allocateOutputBuffer(int /*chunkNumber*/, + rcti *rect) { // we asume that this method is only called from complex execution groups. NodeOperation *operation = this->getOutputOperation(); diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index 4b6f51c72c0..99365cdd4a8 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -347,11 +347,6 @@ public: MemoryBuffer *allocateOutputBuffer(int chunkNumber, rcti *rect); /** - * @brief print execution statistics to stdout when running in a background mode - */ - void printBackgroundStats(void); - - /** * @brief after a chunk is executed the needed resources can be freed or unlocked. * @param chunknumber * @param memorybuffers diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 7c08188db90..caeaa07d9f9 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -43,8 +43,10 @@ extern "C" { #endif ExecutionSystem::ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editingtree, bool rendering, bool fastcalculation, - const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings) + const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings, + const char *viewName) { + this->m_context.setViewName(viewName); this->m_context.setScene(scene); this->m_context.setbNodeTree(editingtree); this->m_context.setPreviewHash(editingtree->previews); @@ -76,6 +78,8 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editin viewer_border->xmin < viewer_border->xmax && viewer_border->ymin < viewer_border->ymax; + editingtree->stats_draw(editingtree->sdh, "Compositing | Determining resolution"); + for (index = 0; index < this->m_groups.size(); index++) { resolution[0] = 0; resolution[1] = 0; @@ -124,6 +128,9 @@ void ExecutionSystem::set_operations(const Operations &operations, const Groups void ExecutionSystem::execute() { + const bNodeTree *editingtree = this->m_context.getbNodeTree(); + editingtree->stats_draw(editingtree->sdh, (char *)"Compositing | Initializing execution"); + DebugInfo::execute_started(this); unsigned int order = 0; @@ -137,11 +144,15 @@ void ExecutionSystem::execute() } unsigned int index; + // First allocale all write buffer for (index = 0; index < this->m_operations.size(); index++) { NodeOperation *operation = this->m_operations[index]; - operation->setbNodeTree(this->m_context.getbNodeTree()); - operation->initExecution(); + if (operation->isWriteBufferOperation()) { + operation->setbNodeTree(this->m_context.getbNodeTree()); + operation->initExecution(); + } } + // Connect read buffers to their write buffers for (index = 0; index < this->m_operations.size(); index++) { NodeOperation *operation = this->m_operations[index]; if (operation->isReadBufferOperation()) { @@ -149,6 +160,14 @@ void ExecutionSystem::execute() readOperation->updateMemoryBuffer(); } } + // initialize other operations + for (index = 0; index < this->m_operations.size(); index++) { + NodeOperation *operation = this->m_operations[index]; + if (!operation->isWriteBufferOperation()) { + operation->setbNodeTree(this->m_context.getbNodeTree()); + operation->initExecution(); + } + } for (index = 0; index < this->m_groups.size(); index++) { ExecutionGroup *executionGroup = this->m_groups[index]; executionGroup->setChunksize(this->m_context.getChunksize()); @@ -166,6 +185,7 @@ void ExecutionSystem::execute() WorkScheduler::finish(); WorkScheduler::stop(); + editingtree->stats_draw(editingtree->sdh, (char *)"Compositing | Deinitializing execution"); for (index = 0; index < this->m_operations.size(); index++) { NodeOperation *operation = this->m_operations[index]; operation->deinitExecution(); diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h index ab903206f0a..41d63fb3a72 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.h +++ b/source/blender/compositor/intern/COM_ExecutionSystem.h @@ -27,14 +27,11 @@ class ExecutionGroup; #include "DNA_color_types.h" #include "DNA_node_types.h" -#include <vector> #include "COM_Node.h" #include "BKE_text.h" #include "COM_ExecutionGroup.h" #include "COM_NodeOperation.h" -using namespace std; - /** * @page execution Execution model * In order to get to an efficient model for execution, several steps are being done. these steps are explained below. @@ -154,7 +151,8 @@ public: * @param rendering [true false] */ ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editingtree, bool rendering, bool fastcalculation, - const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings); + const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings, + const char *viewName); /** * Destructor diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp index c59ecced93c..7ee5e2f7c57 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp @@ -27,6 +27,19 @@ using std::min; using std::max; +static unsigned int determine_num_channels(DataType datatype) +{ + switch (datatype) { + case COM_DT_VALUE: + return COM_NUM_CHANNELS_VALUE; + case COM_DT_VECTOR: + return COM_NUM_CHANNELS_VECTOR; + case COM_DT_COLOR: + default: + return COM_NUM_CHANNELS_COLOR; + } +} + unsigned int MemoryBuffer::determineBufferSize() { return getWidth() * getHeight(); @@ -34,61 +47,62 @@ unsigned int MemoryBuffer::determineBufferSize() int MemoryBuffer::getWidth() const { - return this->m_rect.xmax - this->m_rect.xmin; + return this->m_width; } int MemoryBuffer::getHeight() const { - return this->m_rect.ymax - this->m_rect.ymin; + return this->m_height; } MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect) { BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax); + this->m_width = BLI_rcti_size_x(&this->m_rect); + this->m_height = BLI_rcti_size_y(&this->m_rect); this->m_memoryProxy = memoryProxy; this->m_chunkNumber = chunkNumber; - this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, 16, "COM_MemoryBuffer"); + this->m_num_channels = determine_num_channels(memoryProxy->getDataType()); + this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * this->m_num_channels, 16, "COM_MemoryBuffer"); this->m_state = COM_MB_ALLOCATED; - this->m_datatype = COM_DT_COLOR; - this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin; + this->m_datatype = memoryProxy->getDataType(); } MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect) { BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax); + this->m_width = BLI_rcti_size_x(&this->m_rect); + this->m_height = BLI_rcti_size_y(&this->m_rect); this->m_memoryProxy = memoryProxy; this->m_chunkNumber = -1; - this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, 16, "COM_MemoryBuffer"); + this->m_num_channels = determine_num_channels(memoryProxy->getDataType()); + this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * this->m_num_channels, 16, "COM_MemoryBuffer"); this->m_state = COM_MB_TEMPORARILY; - this->m_datatype = COM_DT_COLOR; - this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin; + this->m_datatype = memoryProxy->getDataType(); +} +MemoryBuffer::MemoryBuffer(DataType dataType, rcti *rect) +{ + BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax); + this->m_width = BLI_rcti_size_x(&this->m_rect); + this->m_height = BLI_rcti_size_y(&this->m_rect); + this->m_height = this->m_rect.ymax - this->m_rect.ymin; + this->m_memoryProxy = NULL; + this->m_chunkNumber = -1; + this->m_num_channels = determine_num_channels(dataType); + this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * this->m_num_channels, 16, "COM_MemoryBuffer"); + this->m_state = COM_MB_TEMPORARILY; + this->m_datatype = dataType; } MemoryBuffer *MemoryBuffer::duplicate() { MemoryBuffer *result = new MemoryBuffer(this->m_memoryProxy, &this->m_rect); - memcpy(result->m_buffer, this->m_buffer, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float)); + memcpy(result->m_buffer, this->m_buffer, this->determineBufferSize() * this->m_num_channels * sizeof(float)); return result; } void MemoryBuffer::clear() { - memset(this->m_buffer, 0, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float)); + memset(this->m_buffer, 0, this->determineBufferSize() * this->m_num_channels * sizeof(float)); } -float *MemoryBuffer::convertToValueBuffer() -{ - const unsigned int size = this->determineBufferSize(); - unsigned int i; - - float *result = (float *)MEM_mallocN(sizeof(float) * size, __func__); - - const float *fp_src = this->m_buffer; - float *fp_dst = result; - - for (i = 0; i < size; i++, fp_dst++, fp_src += COM_NUMBER_OF_CHANNELS) { - *fp_dst = *fp_src; - } - - return result; -} float MemoryBuffer::getMaximumValue() { @@ -98,7 +112,7 @@ float MemoryBuffer::getMaximumValue() const float *fp_src = this->m_buffer; - for (i = 0; i < size; i++, fp_src += COM_NUMBER_OF_CHANNELS) { + for (i = 0; i < size; i++, fp_src += this->m_num_channels) { float value = *fp_src; if (value > result) { result = value; @@ -116,7 +130,7 @@ float MemoryBuffer::getMaximumValue(rcti *rect) BLI_rcti_isect(rect, &this->m_rect, &rect_clamp); if (!BLI_rcti_is_empty(&rect_clamp)) { - MemoryBuffer *temp = new MemoryBuffer(NULL, &rect_clamp); + MemoryBuffer *temp = new MemoryBuffer(this->m_datatype, &rect_clamp); temp->copyContentFrom(this); float result = temp->getMaximumValue(); delete temp; @@ -152,9 +166,9 @@ void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer) for (otherY = minY; otherY < maxY; otherY++) { - otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_chunkWidth + minX - otherBuffer->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; - offset = ((otherY - this->m_rect.ymin) * this->m_chunkWidth + minX - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; - memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * COM_NUMBER_OF_CHANNELS * sizeof(float)); + otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_width + minX - otherBuffer->m_rect.xmin) * this->m_num_channels; + offset = ((otherY - this->m_rect.ymin) * this->m_width + minX - this->m_rect.xmin) * this->m_num_channels; + memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * this->m_num_channels * sizeof(float)); } } @@ -163,9 +177,8 @@ void MemoryBuffer::writePixel(int x, int y, const float color[4]) if (x >= this->m_rect.xmin && x < this->m_rect.xmax && y >= this->m_rect.ymin && y < this->m_rect.ymax) { - const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; - copy_v4_v4(&this->m_buffer[offset], color); - } + const int offset = (this->m_width * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * this->m_num_channels; + memcpy(&this->m_buffer[offset], color, sizeof(float)*this->m_num_channels); } } void MemoryBuffer::addPixel(int x, int y, const float color[4]) @@ -173,63 +186,39 @@ void MemoryBuffer::addPixel(int x, int y, const float color[4]) if (x >= this->m_rect.xmin && x < this->m_rect.xmax && y >= this->m_rect.ymin && y < this->m_rect.ymax) { - const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; - add_v4_v4(&this->m_buffer[offset], color); + const int offset = (this->m_width * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * this->m_num_channels; + float *dst = &this->m_buffer[offset]; + const float *src = color; + for (int i = 0; i < this->m_num_channels ; i++, dst++, src++) { + *dst += *src; + } } } -typedef struct ReadEWAData { - MemoryBuffer *buffer; - PixelSampler sampler; - float ufac, vfac; -} ReadEWAData; - static void read_ewa_pixel_sampled(void *userdata, int x, int y, float result[4]) { - ReadEWAData *data = (ReadEWAData *) userdata; - switch (data->sampler) { - case COM_PS_NEAREST: - data->buffer->read(result, x, y); - break; - case COM_PS_BILINEAR: - data->buffer->readBilinear(result, - (float)x + data->ufac, - (float)y + data->vfac); - break; - case COM_PS_BICUBIC: - /* TOOD(sergey): no readBicubic method yet */ - data->buffer->readBilinear(result, - (float)x + data->ufac, - (float)y + data->vfac); - break; - default: - zero_v4(result); - break; - } + MemoryBuffer *buffer = (MemoryBuffer *) userdata; + buffer->read(result, x, y); } -void MemoryBuffer::readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler) +void MemoryBuffer::readEWA(float *result, const float uv[2], const float derivatives[2][2]) { - ReadEWAData data; - data.buffer = this; - data.sampler = sampler; - data.ufac = uv[0] - floorf(uv[0]); - data.vfac = uv[1] - floorf(uv[1]); - - int width = this->getWidth(), height = this->getHeight(); + BLI_assert(this->m_datatype == COM_DT_COLOR); + float inv_width = 1.0f / (float)this->getWidth(), + inv_height = 1.0f / (float)this->getHeight(); /* TODO(sergey): Render pipeline uses normalized coordinates and derivatives, * but compositor uses pixel space. For now let's just divide the values and * switch compositor to normalized space for EWA later. */ - float uv_normal[2] = {uv[0] / width, uv[1] / height}; - float du_normal[2] = {derivatives[0][0] / width, derivatives[0][1] / height}; - float dv_normal[2] = {derivatives[1][0] / width, derivatives[1][1] / height}; + float uv_normal[2] = {uv[0] * inv_width, uv[1] * inv_height}; + float du_normal[2] = {derivatives[0][0] * inv_width, derivatives[0][1] * inv_height}; + float dv_normal[2] = {derivatives[1][0] * inv_width, derivatives[1][1] * inv_height}; BLI_ewa_filter(this->getWidth(), this->getHeight(), false, true, uv_normal, du_normal, dv_normal, read_ewa_pixel_sampled, - &data, + this, result); } diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h index d6ef9cd673e..de8c14e1a66 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.h +++ b/source/blender/compositor/intern/COM_MemoryBuffer.h @@ -83,11 +83,6 @@ private: unsigned int m_chunkNumber; /** - * @brief width of the chunk - */ - unsigned int m_chunkWidth; - - /** * @brief state of the buffer */ MemoryBufferState m_state; @@ -97,6 +92,15 @@ private: */ float *m_buffer; + /** + * @brief the number of channels of a single value in the buffer. + * For value buffers this is 1, vector 3 and color 4 + */ + unsigned int m_num_channels; + + int m_width; + int m_height; + public: /** * @brief construct new MemoryBuffer for a chunk @@ -107,7 +111,12 @@ public: * @brief construct new temporarily MemoryBuffer for an area */ MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect); - + + /** + * @brief construct new temporarily MemoryBuffer for an area + */ + MemoryBuffer(DataType datatype, rcti *rect); + /** * @brief destructor */ @@ -117,7 +126,9 @@ public: * @brief read the ChunkNumber of this MemoryBuffer */ unsigned int getChunkNumber() { return this->m_chunkNumber; } - + + unsigned int get_num_channels() { return this->m_num_channels; } + /** * @brief get the data of this MemoryBuffer * @note buffer should already be available in memory @@ -134,8 +145,8 @@ public: inline void wrap_pixel(int &x, int &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y) { - int w = m_rect.xmax - m_rect.xmin; - int h = m_rect.ymax - m_rect.ymin; + int w = this->m_width; + int h = this->m_height; x = x - m_rect.xmin; y = y - m_rect.ymin; @@ -164,7 +175,39 @@ public: } } - inline void read(float result[4], int x, int y, + inline void wrap_pixel(float &x, float &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y) + { + float w = (float)this->m_width; + float h = (float)this->m_height; + x = x - m_rect.xmin; + y = y - m_rect.ymin; + + switch (extend_x) { + case COM_MB_CLIP: + break; + case COM_MB_EXTEND: + if (x < 0) x = 0.0f; + if (x >= w) x = w; + break; + case COM_MB_REPEAT: + x = fmodf(x, w); + break; + } + + switch (extend_y) { + case COM_MB_CLIP: + break; + case COM_MB_EXTEND: + if (y < 0) y = 0.0f; + if (y >= h) y = h; + break; + case COM_MB_REPEAT: + y = fmodf(y, h); + break; + } + } + + inline void read(float *result, int x, int y, MemoryBufferExtend extend_x = COM_MB_CLIP, MemoryBufferExtend extend_y = COM_MB_CLIP) { @@ -172,81 +215,54 @@ public: bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)); if (clip_x || clip_y) { /* clip result outside rect is zero */ - zero_v4(result); + memset(result, 0, this->m_num_channels * sizeof(float)); } else { - wrap_pixel(x, y, extend_x, extend_y); - const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS; - copy_v4_v4(result, &this->m_buffer[offset]); + int u = x; + int v = y; + this->wrap_pixel(u, v, extend_x, extend_y); + const int offset = (this->m_width * y + x) * this->m_num_channels; + float *buffer = &this->m_buffer[offset]; + memcpy(result, buffer, sizeof(float) * this->m_num_channels); } } - inline void readNoCheck(float result[4], int x, int y, + inline void readNoCheck(float *result, int x, int y, MemoryBufferExtend extend_x = COM_MB_CLIP, MemoryBufferExtend extend_y = COM_MB_CLIP) { - wrap_pixel(x, y, extend_x, extend_y); - const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS; + int u = x; + int v = y; - BLI_assert(offset >= 0); - BLI_assert(offset < this->determineBufferSize() * COM_NUMBER_OF_CHANNELS); - BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) && - !(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax))); + this->wrap_pixel(u, v, extend_x, extend_y); + const int offset = (this->m_width * v + u) * this->m_num_channels; + BLI_assert(offset >= 0); + BLI_assert(offset < this->determineBufferSize() * this->m_num_channels); + BLI_assert(!(extend_x == COM_MB_CLIP && (u < m_rect.xmin || u >= m_rect.xmax)) && + !(extend_y == COM_MB_CLIP && (v < m_rect.ymin || v >= m_rect.ymax))); #if 0 /* always true */ BLI_assert((int)(MEM_allocN_len(this->m_buffer) / sizeof(*this->m_buffer)) == (int)(this->determineBufferSize() * COM_NUMBER_OF_CHANNELS)); #endif - - copy_v4_v4(result, &this->m_buffer[offset]); + float *buffer = &this->m_buffer[offset]; + memcpy(result, buffer, sizeof(float) * this->m_num_channels); } void writePixel(int x, int y, const float color[4]); void addPixel(int x, int y, const float color[4]); - inline void readBilinear(float result[4], float x, float y, + inline void readBilinear(float *result, float x, float y, MemoryBufferExtend extend_x = COM_MB_CLIP, MemoryBufferExtend extend_y = COM_MB_CLIP) { - int x1 = floor(x); - int y1 = floor(y); - int x2 = x1 + 1; - int y2 = y1 + 1; - wrap_pixel(x1, y1, extend_x, extend_y); - wrap_pixel(x2, y2, extend_x, extend_y); - - float valuex = x - x1; - float valuey = y - y1; - float mvaluex = 1.0f - valuex; - float mvaluey = 1.0f - valuey; - - float color1[4]; - float color2[4]; - float color3[4]; - float color4[4]; - - read(color1, x1, y1); - read(color2, x1, y2); - read(color3, x2, y1); - read(color4, x2, y2); - - color1[0] = color1[0] * mvaluey + color2[0] * valuey; - color1[1] = color1[1] * mvaluey + color2[1] * valuey; - color1[2] = color1[2] * mvaluey + color2[2] * valuey; - color1[3] = color1[3] * mvaluey + color2[3] * valuey; - - color3[0] = color3[0] * mvaluey + color4[0] * valuey; - color3[1] = color3[1] * mvaluey + color4[1] * valuey; - color3[2] = color3[2] * mvaluey + color4[2] * valuey; - color3[3] = color3[3] * mvaluey + color4[3] * valuey; - - result[0] = color1[0] * mvaluex + color3[0] * valuex; - result[1] = color1[1] * mvaluex + color3[1] * valuex; - result[2] = color1[2] * mvaluex + color3[2] * valuex; - result[3] = color1[3] * mvaluex + color3[3] * valuex; + float u = x; + float v = y; + this->wrap_pixel(u, v, extend_x, extend_y); + BLI_bilinear_interpolation_fl(this->m_buffer, result, this->m_width, this->m_height, this->m_num_channels, u, v); } - void readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler); + void readEWA(float *result, const float uv[2], const float derivatives[2][2]); /** * @brief is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk) @@ -284,7 +300,6 @@ public: MemoryBuffer *duplicate(); - float *convertToValueBuffer(); float getMaximumValue(); float getMaximumValue(rcti *rect); private: diff --git a/source/blender/compositor/intern/COM_MemoryProxy.cpp b/source/blender/compositor/intern/COM_MemoryProxy.cpp index 90ca0baea06..1df3e59db62 100644 --- a/source/blender/compositor/intern/COM_MemoryProxy.cpp +++ b/source/blender/compositor/intern/COM_MemoryProxy.cpp @@ -23,10 +23,11 @@ #include "COM_MemoryProxy.h" -MemoryProxy::MemoryProxy() +MemoryProxy::MemoryProxy(DataType datatype) { this->m_writeBufferOperation = NULL; this->m_executor = NULL; + this->m_datatype = datatype; } void MemoryProxy::allocate(unsigned int width, unsigned int height) diff --git a/source/blender/compositor/intern/COM_MemoryProxy.h b/source/blender/compositor/intern/COM_MemoryProxy.h index 233b035a2d7..b332852088b 100644 --- a/source/blender/compositor/intern/COM_MemoryProxy.h +++ b/source/blender/compositor/intern/COM_MemoryProxy.h @@ -63,8 +63,13 @@ private: */ MemoryBuffer *m_buffer; + /** + * @brief datatype of this MemoryProxy + */ + DataType m_datatype; + public: - MemoryProxy(); + MemoryProxy(DataType type); /** * @brief set the ExecutionGroup that can be scheduled to calculate a certain chunk. @@ -104,6 +109,8 @@ public: */ inline MemoryBuffer *getBuffer() { return this->m_buffer; } + inline DataType getDataType() { return this->m_datatype; } + #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryProxy") #endif diff --git a/source/blender/compositor/intern/COM_NodeGraph.cpp b/source/blender/compositor/intern/COM_NodeGraph.cpp index 2dcf419d81b..c5096a6b352 100644 --- a/source/blender/compositor/intern/COM_NodeGraph.cpp +++ b/source/blender/compositor/intern/COM_NodeGraph.cpp @@ -179,6 +179,8 @@ void NodeGraph::add_bNodeLink(const NodeRange &node_range, bNodeLink *b_nodelink /// @note: ignore invalid links if (!(b_nodelink->flag & NODE_LINK_VALID)) return; + if ((b_nodelink->fromsock->flag & SOCK_UNAVAIL) || (b_nodelink->tosock->flag & SOCK_UNAVAIL)) + return; /* Note: a DNA input socket can have multiple NodeInput in the compositor tree! (proxies) * The output then gets linked to each one of them. diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index d9c16615fb6..7c87524b4b3 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -161,7 +161,7 @@ public: * * @return bool the result of this method */ - virtual bool isOutputOperation(bool rendering) const { return false; } + virtual bool isOutputOperation(bool /*rendering*/) const { return false; } virtual int isSingleThreaded() { return false; } @@ -175,7 +175,8 @@ public: * @param chunkNumber the chunkNumber to be calculated * @param memoryBuffers all input MemoryBuffer's needed */ - virtual void executeRegion(rcti *rect, unsigned int chunkNumber) {} + virtual void executeRegion(rcti * /*rect*/, + unsigned int /*chunkNumber*/) {} /** * @brief when a chunk is executed by an OpenCLDevice, this method is called @@ -189,8 +190,11 @@ public: * @param memoryBuffers all input MemoryBuffer's needed * @param outputBuffer the outputbuffer to write to */ - virtual void executeOpenCLRegion(OpenCLDevice *device, rcti *rect, - unsigned int chunkNumber, MemoryBuffer **memoryBuffers, MemoryBuffer *outputBuffer) {} + virtual void executeOpenCLRegion(OpenCLDevice * /*device*/, + 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 @@ -204,10 +208,12 @@ public: * @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(OpenCLDevice *device, - MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, - MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, - list<cl_kernel> *clKernelsToCleanUp) {} + virtual void executeOpenCL(OpenCLDevice * /*device*/, + MemoryBuffer * /*outputMemoryBuffer*/, + cl_mem /*clOutputBuffer*/, + MemoryBuffer ** /*inputMemoryBuffers*/, + list<cl_mem> * /*clMemToCleanUp*/, + list<cl_kernel> * /*clKernelsToCleanUp*/) {} virtual void deinitExecution(); bool isResolutionSet() { diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp b/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp index fb5bc8fcd9b..e899b7b14fd 100644 --- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp +++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp @@ -101,12 +101,12 @@ void NodeOperationBuilder::convertToOperations(ExecutionSystem *system) } } - add_datatype_conversions(); - add_operation_input_constants(); resolve_proxies(); + add_datatype_conversions(); + determineResolutions(); /* surround complex ops with read/write buffer */ @@ -459,7 +459,8 @@ WriteBufferOperation *NodeOperationBuilder::find_attached_write_buffer_operation return NULL; } -void NodeOperationBuilder::add_input_buffers(NodeOperation *operation, NodeOperationInput *input) +void NodeOperationBuilder::add_input_buffers(NodeOperation * /*operation*/, + NodeOperationInput *input) { if (!input->isConnected()) return; @@ -476,7 +477,7 @@ void NodeOperationBuilder::add_input_buffers(NodeOperation *operation, NodeOpera /* check of other end already has write operation, otherwise add a new one */ WriteBufferOperation *writeoperation = find_attached_write_buffer_operation(output); if (!writeoperation) { - writeoperation = new WriteBufferOperation(); + writeoperation = new WriteBufferOperation(output->getDataType()); writeoperation->setbNodeTree(m_context->getbNodeTree()); addOperation(writeoperation); @@ -486,7 +487,7 @@ void NodeOperationBuilder::add_input_buffers(NodeOperation *operation, NodeOpera } /* add readbuffer op for the input */ - ReadBufferOperation *readoperation = new ReadBufferOperation(); + ReadBufferOperation *readoperation = new ReadBufferOperation(output->getDataType()); readoperation->setMemoryProxy(writeoperation->getMemoryProxy()); this->addOperation(readoperation); @@ -519,7 +520,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOper /* if no write buffer operation exists yet, create a new one */ if (!writeOperation) { - writeOperation = new WriteBufferOperation(); + writeOperation = new WriteBufferOperation(operation->getOutputSocket()->getDataType()); writeOperation->setbNodeTree(m_context->getbNodeTree()); addOperation(writeOperation); @@ -534,7 +535,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOper if (&target->getOperation() == writeOperation) continue; /* skip existing write op links */ - ReadBufferOperation *readoperation = new ReadBufferOperation(); + ReadBufferOperation *readoperation = new ReadBufferOperation(operation->getOutputSocket()->getDataType()); readoperation->setMemoryProxy(writeOperation->getMemoryProxy()); addOperation(readoperation); diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cpp b/source/blender/compositor/intern/COM_OpenCLDevice.cpp index c5b663d2aef..1c9e59a4b7a 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.cpp +++ b/source/blender/compositor/intern/COM_OpenCLDevice.cpp @@ -24,6 +24,18 @@ #include "COM_WorkScheduler.h" typedef enum COM_VendorID {NVIDIA = 0x10DE, AMD = 0x1002} COM_VendorID; +const cl_image_format IMAGE_FORMAT_COLOR = { + CL_RGBA, + CL_FLOAT +}; +const cl_image_format IMAGE_FORMAT_VECTOR = { + CL_RGB, + CL_FLOAT +}; +const cl_image_format IMAGE_FORMAT_VALUE = { + CL_R, + CL_FLOAT +}; OpenCLDevice::OpenCLDevice(cl_context context, cl_device_id device, cl_program program, cl_int vendorId) { @@ -72,6 +84,23 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, return COM_clAttachMemoryBufferToKernelParameter(kernel, parameterIndex, offsetIndex, cleanup, inputMemoryBuffers, (ReadBufferOperation *)reader); } +const cl_image_format *OpenCLDevice::determineImageFormat(MemoryBuffer *memoryBuffer) +{ + const cl_image_format *imageFormat; + int num_channels = memoryBuffer->get_num_channels(); + if (num_channels == 1) { + imageFormat = &IMAGE_FORMAT_VALUE; + } + else if (num_channels == 3) { + imageFormat = &IMAGE_FORMAT_VECTOR; + } + else { + imageFormat = &IMAGE_FORMAT_COLOR; + } + + return imageFormat; +} + cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, ReadBufferOperation *reader) @@ -80,12 +109,9 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, MemoryBuffer *result = reader->getInputMemoryBuffer(inputMemoryBuffers); - const cl_image_format imageFormat = { - CL_RGBA, - CL_FLOAT - }; + const cl_image_format *imageFormat = determineImageFormat(result); - cl_mem clBuffer = clCreateImage2D(this->m_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &imageFormat, result->getWidth(), + cl_mem clBuffer = clCreateImage2D(this->m_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, imageFormat, result->getWidth(), result->getHeight(), 0, result->getBuffer(), &error); if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } @@ -154,7 +180,7 @@ void OpenCLDevice::COM_clEnqueueRange(cl_kernel kernel, MemoryBuffer *outputMemo bool breaked = false; for (offsety = 0; offsety < height && (!breaked); offsety += localSize) { - offset.y = offsety; + offset.s[1] = offsety; if (offsety + localSize < height) { size[1] = localSize; } @@ -169,7 +195,7 @@ void OpenCLDevice::COM_clEnqueueRange(cl_kernel kernel, MemoryBuffer *outputMemo else { size[0] = width - offsetx; } - offset.x = offsetx; + offset.s[0] = offsetx; error = clSetKernelArg(kernel, offsetIndex, sizeof(cl_int2), &offset); if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.h b/source/blender/compositor/intern/COM_OpenCLDevice.h index 94df2f2b44c..a513954ee0d 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.h +++ b/source/blender/compositor/intern/COM_OpenCLDevice.h @@ -94,6 +94,12 @@ public: */ void execute(WorkPackage *work); + /** + * @brief determine an image format + * @param memorybuffer + */ + static const cl_image_format *determineImageFormat(MemoryBuffer *memoryBuffer); + cl_context getContext() { return this->m_context; } cl_command_queue getQueue() { return this->m_queue; } diff --git a/source/blender/compositor/intern/COM_SingleThreadedOperation.cpp b/source/blender/compositor/intern/COM_SingleThreadedOperation.cpp index c300a85bfa3..b17f5d6b429 100644 --- a/source/blender/compositor/intern/COM_SingleThreadedOperation.cpp +++ b/source/blender/compositor/intern/COM_SingleThreadedOperation.cpp @@ -33,7 +33,7 @@ void SingleThreadedOperation::initExecution() initMutex(); } -void SingleThreadedOperation::executePixel(float output[4], int x, int y, void *data) +void SingleThreadedOperation::executePixel(float output[4], int x, int y, void * /*data*/) { this->m_cachedInstance->readNoCheck(output, x, y); } diff --git a/source/blender/compositor/intern/COM_SocketReader.h b/source/blender/compositor/intern/COM_SocketReader.h index c996ef5bbeb..ab8a3c06ef5 100644 --- a/source/blender/compositor/intern/COM_SocketReader.h +++ b/source/blender/compositor/intern/COM_SocketReader.h @@ -63,7 +63,10 @@ protected: * @param y the y-coordinate of the pixel to calculate in image space * @param inputBuffers chunks that can be read by their ReadBufferOperation. */ - virtual void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) {} + virtual void executePixelSampled(float /*output*/[4], + float /*x*/, + float /*y*/, + PixelSampler /*sampler*/) { } /** * @brief calculate a single pixel @@ -74,7 +77,7 @@ protected: * @param inputBuffers chunks that can be read by their ReadBufferOperation. * @param chunkData chunk specific data a during execution time. */ - virtual void executePixel(float output[4], int x, int y, void *chunkData) { + virtual void executePixel(float output[4], int x, int y, void * /*chunkData*/) { executePixelSampled(output, x, y, COM_PS_NEAREST); } @@ -88,7 +91,9 @@ protected: * @param dy * @param inputBuffers chunks that can be read by their ReadBufferOperation. */ - virtual void executePixelFiltered(float output[4], float x, float y, float dx[2], float dy[2], PixelSampler sampler) {} + virtual void executePixelFiltered(float /*output*/[4], + float /*x*/, float /*y*/, + float /*dx*/[2], float /*dy*/[2]) {} public: inline void readSampled(float result[4], float x, float y, PixelSampler sampler) { @@ -97,16 +102,16 @@ public: inline void read(float result[4], int x, int y, void *chunkData) { executePixel(result, x, y, chunkData); } - inline void readFiltered(float result[4], float x, float y, float dx[2], float dy[2], PixelSampler sampler) { - executePixelFiltered(result, x, y, dx, dy, sampler); + inline void readFiltered(float result[4], float x, float y, float dx[2], float dy[2]) { + executePixelFiltered(result, x, y, dx, dy); } - virtual void *initializeTileData(rcti *rect) { return 0; } - virtual void deinitializeTileData(rcti *rect, void *data) {} + virtual void *initializeTileData(rcti * /*rect*/) { return 0; } + virtual void deinitializeTileData(rcti * /*rect*/, void * /*data*/) {} virtual ~SocketReader() {} - virtual MemoryBuffer *getInputMemoryBuffer(MemoryBuffer **memoryBuffers) { return 0; } + virtual MemoryBuffer *getInputMemoryBuffer(MemoryBuffer ** /*memoryBuffers*/) { return 0; } inline const unsigned int getWidth() const { return this->m_width; } inline const unsigned int getHeight() const { return this->m_height; } diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp index e1016731c7f..fc6ea1299cf 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cpp +++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp @@ -111,7 +111,9 @@ static void **g_highlightedNodesRead; } #endif /* COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE */ #else +# if COM_CURRENT_THREADING_MODEL != COM_TM_NOTHREAD #define HIGHLIGHT(wp) {} +# endif #endif void COM_startReadHighlights() @@ -196,7 +198,7 @@ void WorkScheduler::schedule(ExecutionGroup *group, int chunkNumber) BLI_thread_queue_push(g_cpuqueue, package); } #else - BLI_thread_queue_push(cpuqueue, package); + BLI_thread_queue_push(g_cpuqueue, package); #endif #endif } @@ -274,7 +276,10 @@ bool WorkScheduler::hasGPUDevices() #endif } -static void CL_CALLBACK clContextError(const char *errinfo, const void *private_info, size_t cb, void *user_data) +static void CL_CALLBACK clContextError(const char *errinfo, + const void * /*private_info*/, + size_t /*cb*/, + void * /*user_data*/) { printf("OPENCL error: %s\n", errinfo); } diff --git a/source/blender/compositor/intern/COM_compositor.cpp b/source/blender/compositor/intern/COM_compositor.cpp index ec9ef6c7e68..7f7fc141aca 100644 --- a/source/blender/compositor/intern/COM_compositor.cpp +++ b/source/blender/compositor/intern/COM_compositor.cpp @@ -45,7 +45,8 @@ static void intern_freeCompositorCaches() void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rendering, const ColorManagedViewSettings *viewSettings, - const ColorManagedDisplaySettings *displaySettings) + const ColorManagedDisplaySettings *displaySettings, + const char *viewName) { /* initialize mutex, TODO this mutex init is actually not thread safe and * should be done somewhere as part of blender startup, all the other @@ -77,11 +78,12 @@ void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rende /* set progress bar to 0% and status to init compositing */ editingtree->progress(editingtree->prh, 0.0); + editingtree->stats_draw(editingtree->sdh, (char *)"Compositing"); bool twopass = (editingtree->flag & NTREE_TWO_PASS) > 0 && !rendering; /* initialize execution system */ if (twopass) { - ExecutionSystem *system = new ExecutionSystem(rd, scene, editingtree, rendering, twopass, viewSettings, displaySettings); + ExecutionSystem *system = new ExecutionSystem(rd, scene, editingtree, rendering, twopass, viewSettings, displaySettings, viewName); system->execute(); delete system; @@ -94,7 +96,7 @@ void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rende } ExecutionSystem *system = new ExecutionSystem(rd, scene, editingtree, rendering, false, - viewSettings, displaySettings); + viewSettings, displaySettings, viewName); system->execute(); delete system; diff --git a/source/blender/compositor/nodes/COM_AlphaOverNode.cpp b/source/blender/compositor/nodes/COM_AlphaOverNode.cpp index 0306d636c8b..e9b99b6aaf1 100644 --- a/source/blender/compositor/nodes/COM_AlphaOverNode.cpp +++ b/source/blender/compositor/nodes/COM_AlphaOverNode.cpp @@ -30,7 +30,7 @@ #include "COM_SetValueOperation.h" #include "DNA_material_types.h" // the ramp types -void AlphaOverNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void AlphaOverNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *color1Socket = this->getInputSocket(1); NodeInput *color2Socket = this->getInputSocket(2); diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp index 76e52c14685..f3d0c33d3b3 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BlurNode.cpp @@ -105,6 +105,7 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon GaussianXBlurOperation *operationx = new GaussianXBlurOperation(); operationx->setData(data); operationx->setQuality(quality); + operationx->checkOpenCL(); converter.addOperation(operationx); converter.mapInputSocket(getInputSocket(1), operationx->getInputSocket(1)); @@ -112,6 +113,7 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon GaussianYBlurOperation *operationy = new GaussianYBlurOperation(); operationy->setData(data); operationy->setQuality(quality); + operationy->checkOpenCL(); converter.addOperation(operationy); converter.mapInputSocket(getInputSocket(1), operationy->getInputSocket(1)); diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp index 636660bc96c..7ab05e438ec 100644 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp @@ -62,8 +62,13 @@ void BokehBlurNode::convertToOperations(NodeConverter &converter, const Composit converter.addOperation(operation); converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0)); converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1)); - converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2)); - converter.mapInputSocket(getInputSocket(3), operation->getInputSocket(3)); + + // NOTE: on the bokeh blur operation the sockets are switched. + // for this reason the next two lines are correct. + // Fix for T43771 + converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(3)); + converter.mapInputSocket(getInputSocket(3), operation->getInputSocket(2)); + converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket()); if (!connectedSizeSocket) { diff --git a/source/blender/compositor/nodes/COM_BokehImageNode.cpp b/source/blender/compositor/nodes/COM_BokehImageNode.cpp index c75e9b16336..7b7cfc812aa 100644 --- a/source/blender/compositor/nodes/COM_BokehImageNode.cpp +++ b/source/blender/compositor/nodes/COM_BokehImageNode.cpp @@ -29,7 +29,7 @@ BokehImageNode::BokehImageNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void BokehImageNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void BokehImageNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { BokehImageOperation *operation = new BokehImageOperation(); operation->setData((NodeBokehImage *)this->getbNode()->storage); diff --git a/source/blender/compositor/nodes/COM_BrightnessNode.cpp b/source/blender/compositor/nodes/COM_BrightnessNode.cpp index e684b569945..053f286c66e 100644 --- a/source/blender/compositor/nodes/COM_BrightnessNode.cpp +++ b/source/blender/compositor/nodes/COM_BrightnessNode.cpp @@ -29,7 +29,7 @@ BrightnessNode::BrightnessNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void BrightnessNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void BrightnessNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { BrightnessOperation *operation = new BrightnessOperation(); converter.addOperation(operation); diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp b/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp index f356c74cd49..cc573274c34 100644 --- a/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp @@ -30,44 +30,48 @@ ChannelMatteNode::ChannelMatteNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void ChannelMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ChannelMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *node = this->getbNode(); - + NodeInput *inputSocketImage = this->getInputSocket(0); NodeOutput *outputSocketImage = this->getOutputSocket(0); NodeOutput *outputSocketMatte = this->getOutputSocket(1); - - NodeOperation *convert = NULL; + + NodeOperation *convert = NULL, *inv_convert = NULL; /* colorspace */ switch (node->custom1) { case CMP_NODE_CHANNEL_MATTE_CS_RGB: break; case CMP_NODE_CHANNEL_MATTE_CS_HSV: /* HSV */ convert = new ConvertRGBToHSVOperation(); + inv_convert = new ConvertHSVToRGBOperation(); break; case CMP_NODE_CHANNEL_MATTE_CS_YUV: /* YUV */ convert = new ConvertRGBToYUVOperation(); + inv_convert = new ConvertYUVToRGBOperation(); break; case CMP_NODE_CHANNEL_MATTE_CS_YCC: /* YCC */ convert = new ConvertRGBToYCCOperation(); ((ConvertRGBToYCCOperation *)convert)->setMode(0); /* BLI_YCC_ITU_BT601 */ + inv_convert = new ConvertYCCToRGBOperation(); + ((ConvertYCCToRGBOperation *)inv_convert)->setMode(0); /* BLI_YCC_ITU_BT601 */ break; default: break; } - + ChannelMatteOperation *operation = new ChannelMatteOperation(); /* pass the ui properties to the operation */ operation->setSettings((NodeChroma *)node->storage, node->custom2); converter.addOperation(operation); - + SetAlphaOperation *operationAlpha = new SetAlphaOperation(); converter.addOperation(operationAlpha); - - if (convert) { + + if (convert != NULL) { converter.addOperation(convert); - + converter.mapInputSocket(inputSocketImage, convert->getInputSocket(0)); converter.addLink(convert->getOutputSocket(), operation->getInputSocket(0)); converter.addLink(convert->getOutputSocket(), operationAlpha->getInputSocket(0)); @@ -76,11 +80,18 @@ void ChannelMatteNode::convertToOperations(NodeConverter &converter, const Compo converter.mapInputSocket(inputSocketImage, operation->getInputSocket(0)); converter.mapInputSocket(inputSocketImage, operationAlpha->getInputSocket(0)); } - + converter.mapOutputSocket(outputSocketMatte, operation->getOutputSocket(0)); - converter.addLink(operation->getOutputSocket(), operationAlpha->getInputSocket(1)); - converter.mapOutputSocket(outputSocketImage, operationAlpha->getOutputSocket()); - - converter.addPreview(operationAlpha->getOutputSocket()); + + if (inv_convert != NULL) { + converter.addOperation(inv_convert); + converter.addLink(operationAlpha->getOutputSocket(0), inv_convert->getInputSocket(0)); + converter.mapOutputSocket(outputSocketImage, inv_convert->getOutputSocket()); + converter.addPreview(inv_convert->getOutputSocket()); + } + else { + converter.mapOutputSocket(outputSocketImage, operationAlpha->getOutputSocket()); + converter.addPreview(operationAlpha->getOutputSocket()); + } } diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp b/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp index 90de9358587..6324ca9a3ca 100644 --- a/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp @@ -30,7 +30,7 @@ ChromaMatteNode::ChromaMatteNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void ChromaMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ChromaMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *editorsnode = getbNode(); diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp b/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp index fc0df046e86..a531493d486 100644 --- a/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp @@ -32,7 +32,7 @@ ColorBalanceNode::ColorBalanceNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void ColorBalanceNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ColorBalanceNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *node = this->getbNode(); NodeColorBalance *n = (NodeColorBalance *)node->storage; diff --git a/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp b/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp index 728b51b8dc1..e926d131c1a 100644 --- a/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp @@ -29,7 +29,7 @@ ColorCorrectionNode::ColorCorrectionNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void ColorCorrectionNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ColorCorrectionNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *editorNode = getbNode(); diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.cpp b/source/blender/compositor/nodes/COM_ColorCurveNode.cpp index 6dc936302f4..5a4dc79e6b2 100644 --- a/source/blender/compositor/nodes/COM_ColorCurveNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorCurveNode.cpp @@ -29,7 +29,7 @@ ColorCurveNode::ColorCurveNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void ColorCurveNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ColorCurveNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { if (this->getInputSocket(2)->isLinked() || this->getInputSocket(3)->isLinked()) { ColorCurveOperation *operation = new ColorCurveOperation(); diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.cpp b/source/blender/compositor/nodes/COM_ColorMatteNode.cpp index def3b18e0fe..f7c20894087 100644 --- a/source/blender/compositor/nodes/COM_ColorMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorMatteNode.cpp @@ -30,7 +30,7 @@ ColorMatteNode::ColorMatteNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void ColorMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ColorMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *editorsnode = getbNode(); diff --git a/source/blender/compositor/nodes/COM_ColorNode.cpp b/source/blender/compositor/nodes/COM_ColorNode.cpp index 4106cb64798..c3770e79dea 100644 --- a/source/blender/compositor/nodes/COM_ColorNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorNode.cpp @@ -29,7 +29,7 @@ ColorNode::ColorNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void ColorNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ColorNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { SetColorOperation *operation = new SetColorOperation(); NodeOutput *output = this->getOutputSocket(0); diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.cpp b/source/blender/compositor/nodes/COM_ColorRampNode.cpp index a61ddffbf35..1feaa88bebb 100644 --- a/source/blender/compositor/nodes/COM_ColorRampNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorRampNode.cpp @@ -32,7 +32,7 @@ ColorRampNode::ColorRampNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void ColorRampNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ColorRampNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *inputSocket = this->getInputSocket(0); NodeOutput *outputSocket = this->getOutputSocket(0); diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.cpp b/source/blender/compositor/nodes/COM_ColorSpillNode.cpp index 82454ba7979..f33f2858397 100644 --- a/source/blender/compositor/nodes/COM_ColorSpillNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorSpillNode.cpp @@ -29,7 +29,7 @@ ColorSpillNode::ColorSpillNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void ColorSpillNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ColorSpillNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *editorsnode = getbNode(); @@ -38,16 +38,10 @@ void ColorSpillNode::convertToOperations(NodeConverter &converter, const Composi NodeOutput *outputSocketImage = this->getOutputSocket(0); ColorSpillOperation *operation; - if (editorsnode->custom2 == 0) { - // Simple color spill - operation = new ColorSpillOperation(); - } - else { - // Average color spill - operation = new ColorSpillAverageOperation(); - } + operation = new ColorSpillOperation(); operation->setSettings((NodeColorspill *)editorsnode->storage); operation->setSpillChannel(editorsnode->custom1 - 1); // Channel for spilling + operation->setSpillMethod(editorsnode->custom2); // Channel method converter.addOperation(operation); converter.mapInputSocket(inputSocketImage, operation->getInputSocket(0)); diff --git a/source/blender/compositor/nodes/COM_ColorToBWNode.cpp b/source/blender/compositor/nodes/COM_ColorToBWNode.cpp index a1616a61b4b..f09c6bac3ee 100644 --- a/source/blender/compositor/nodes/COM_ColorToBWNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorToBWNode.cpp @@ -30,7 +30,7 @@ ColorToBWNode::ColorToBWNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void ColorToBWNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ColorToBWNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *colorSocket = this->getInputSocket(0); NodeOutput *valueSocket = this->getOutputSocket(0); diff --git a/source/blender/compositor/nodes/COM_CombineColorNode.cpp b/source/blender/compositor/nodes/COM_CombineColorNode.cpp index c7a3baf809d..a39e946fe5f 100644 --- a/source/blender/compositor/nodes/COM_CombineColorNode.cpp +++ b/source/blender/compositor/nodes/COM_CombineColorNode.cpp @@ -72,17 +72,17 @@ void CombineColorNode::convertToOperations(NodeConverter &converter, const Compo } -NodeOperation *CombineRGBANode::getColorConverter(const CompositorContext &context) const +NodeOperation *CombineRGBANode::getColorConverter(const CompositorContext &/*context*/) const { return NULL; /* no conversion needed */ } -NodeOperation *CombineHSVANode::getColorConverter(const CompositorContext &context) const +NodeOperation *CombineHSVANode::getColorConverter(const CompositorContext &/*context*/) const { return new ConvertHSVToRGBOperation(); } -NodeOperation *CombineYCCANode::getColorConverter(const CompositorContext &context) const +NodeOperation *CombineYCCANode::getColorConverter(const CompositorContext &/*context*/) const { ConvertYCCToRGBOperation *operation = new ConvertYCCToRGBOperation(); bNode *editorNode = this->getbNode(); @@ -90,7 +90,7 @@ NodeOperation *CombineYCCANode::getColorConverter(const CompositorContext &conte return operation; } -NodeOperation *CombineYUVANode::getColorConverter(const CompositorContext &context) const +NodeOperation *CombineYUVANode::getColorConverter(const CompositorContext &/*context*/) const { return new ConvertYUVToRGBOperation(); } diff --git a/source/blender/compositor/nodes/COM_CompositorNode.cpp b/source/blender/compositor/nodes/COM_CompositorNode.cpp index 3d79eb693ea..9e8b40d8af4 100644 --- a/source/blender/compositor/nodes/COM_CompositorNode.cpp +++ b/source/blender/compositor/nodes/COM_CompositorNode.cpp @@ -34,7 +34,7 @@ void CompositorNode::convertToOperations(NodeConverter &converter, const Composi bNode *editorNode = this->getbNode(); bool is_active = (editorNode->flag & NODE_DO_OUTPUT_RECALC) || context.isRendering(); - bool ignore_alpha = editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA; + bool ignore_alpha = (editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA) != 0; NodeInput *imageSocket = this->getInputSocket(0); NodeInput *alphaSocket = this->getInputSocket(1); @@ -43,6 +43,7 @@ void CompositorNode::convertToOperations(NodeConverter &converter, const Composi CompositorOperation *compositorOperation = new CompositorOperation(); compositorOperation->setSceneName(context.getScene()->id.name); compositorOperation->setRenderData(context.getRenderData()); + compositorOperation->setViewName(context.getViewName()); compositorOperation->setbNodeTree(context.getbNodeTree()); /* alpha socket gives either 1 or a custom alpha value if "use alpha" is enabled */ compositorOperation->setUseAlphaInput(ignore_alpha || alphaSocket->isLinked()); diff --git a/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp b/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp index ba31ed6e89c..fbf5dbb6253 100644 --- a/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp +++ b/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp @@ -23,7 +23,7 @@ #include "COM_ConvertOperation.h" #include "COM_ExecutionSystem.h" -void ConvertAlphaNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ConvertAlphaNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeOperation *operation = NULL; bNode *node = this->getbNode(); diff --git a/source/blender/compositor/nodes/COM_CornerPinNode.cpp b/source/blender/compositor/nodes/COM_CornerPinNode.cpp index ea9f22f2840..5e4e463595a 100644 --- a/source/blender/compositor/nodes/COM_CornerPinNode.cpp +++ b/source/blender/compositor/nodes/COM_CornerPinNode.cpp @@ -28,7 +28,7 @@ CornerPinNode::CornerPinNode(bNode *editorNode) : Node(editorNode) { } -void CornerPinNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void CornerPinNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *input_image = this->getInputSocket(0); /* note: socket order differs between UI node and operations: diff --git a/source/blender/compositor/nodes/COM_CropNode.cpp b/source/blender/compositor/nodes/COM_CropNode.cpp index 6c3dc93481b..ee148f41c68 100644 --- a/source/blender/compositor/nodes/COM_CropNode.cpp +++ b/source/blender/compositor/nodes/COM_CropNode.cpp @@ -29,7 +29,7 @@ CropNode::CropNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void CropNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void CropNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *node = getbNode(); NodeTwoXYs *cropSettings = (NodeTwoXYs *)node->storage; diff --git a/source/blender/compositor/nodes/COM_DespeckleNode.cpp b/source/blender/compositor/nodes/COM_DespeckleNode.cpp index bac6337374f..a21885bf42d 100644 --- a/source/blender/compositor/nodes/COM_DespeckleNode.cpp +++ b/source/blender/compositor/nodes/COM_DespeckleNode.cpp @@ -29,7 +29,7 @@ DespeckleNode::DespeckleNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void DespeckleNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void DespeckleNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *editorNode = this->getbNode(); NodeInput *inputSocket = this->getInputSocket(0); diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp b/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp index 8870badab09..2cb0e2301ac 100644 --- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp @@ -30,7 +30,7 @@ DifferenceMatteNode::DifferenceMatteNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void DifferenceMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void DifferenceMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *inputSocket = this->getInputSocket(0); NodeInput *inputSocket2 = this->getInputSocket(1); diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp b/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp index 704c704c500..99061cf8824 100644 --- a/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp @@ -31,7 +31,7 @@ DistanceMatteNode::DistanceMatteNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void DistanceMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void DistanceMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *editorsnode = getbNode(); NodeChroma *storage = (NodeChroma *)editorsnode->storage; @@ -66,6 +66,8 @@ void DistanceMatteNode::convertToOperations(NodeConverter &converter, const Comp ConvertRGBToYCCOperation *operationYCCImage = new ConvertRGBToYCCOperation(); ConvertRGBToYCCOperation *operationYCCMatte = new ConvertRGBToYCCOperation(); + operationYCCImage->setMode(0); /* BLI_YCC_ITU_BT601 */ + operationYCCMatte->setMode(0); /* BLI_YCC_ITU_BT601 */ converter.addOperation(operationYCCImage); converter.addOperation(operationYCCMatte); @@ -79,10 +81,20 @@ void DistanceMatteNode::convertToOperations(NodeConverter &converter, const Comp operation = matte; } + converter.mapOutputSocket(outputSocketMatte, operation->getOutputSocket(0)); converter.addLink(operation->getOutputSocket(), operationAlpha->getInputSocket(1)); - converter.mapOutputSocket(outputSocketMatte, operation->getOutputSocket()); - converter.mapOutputSocket(outputSocketImage, operationAlpha->getOutputSocket()); - - converter.addPreview(operationAlpha->getOutputSocket()); + if (storage->channel != 1) { + ConvertYCCToRGBOperation *inv_convert = new ConvertYCCToRGBOperation(); + inv_convert->setMode(0); /* BLI_YCC_ITU_BT601 */ + + converter.addOperation(inv_convert); + converter.addLink(operationAlpha->getOutputSocket(0), inv_convert->getInputSocket(0)); + converter.mapOutputSocket(outputSocketImage, inv_convert->getOutputSocket()); + converter.addPreview(inv_convert->getOutputSocket()); + } + else { + converter.mapOutputSocket(outputSocketImage, operationAlpha->getOutputSocket()); + converter.addPreview(operationAlpha->getOutputSocket()); + } } diff --git a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp index 1f80eeadf83..c67abb1ab99 100644 --- a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp +++ b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp @@ -29,7 +29,7 @@ DoubleEdgeMaskNode::DoubleEdgeMaskNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void DoubleEdgeMaskNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void DoubleEdgeMaskNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { DoubleEdgeMaskOperation *operation; bNode *bnode = this->getbNode(); diff --git a/source/blender/compositor/nodes/COM_FilterNode.cpp b/source/blender/compositor/nodes/COM_FilterNode.cpp index 9f3a7ae795c..7493f24ba6b 100644 --- a/source/blender/compositor/nodes/COM_FilterNode.cpp +++ b/source/blender/compositor/nodes/COM_FilterNode.cpp @@ -32,7 +32,7 @@ FilterNode::FilterNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void FilterNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void FilterNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *inputSocket = this->getInputSocket(0); NodeInput *inputImageSocket = this->getInputSocket(1); diff --git a/source/blender/compositor/nodes/COM_FlipNode.cpp b/source/blender/compositor/nodes/COM_FlipNode.cpp index 1dbcc97143e..0177dc7017a 100644 --- a/source/blender/compositor/nodes/COM_FlipNode.cpp +++ b/source/blender/compositor/nodes/COM_FlipNode.cpp @@ -30,7 +30,7 @@ FlipNode::FlipNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void FlipNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void FlipNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *inputSocket = this->getInputSocket(0); NodeOutput *outputSocket = this->getOutputSocket(0); diff --git a/source/blender/compositor/nodes/COM_GammaNode.cpp b/source/blender/compositor/nodes/COM_GammaNode.cpp index 046cd9e9a0d..bf24bee55d3 100644 --- a/source/blender/compositor/nodes/COM_GammaNode.cpp +++ b/source/blender/compositor/nodes/COM_GammaNode.cpp @@ -29,7 +29,7 @@ GammaNode::GammaNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void GammaNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void GammaNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { GammaOperation *operation = new GammaOperation(); converter.addOperation(operation); diff --git a/source/blender/compositor/nodes/COM_GlareNode.cpp b/source/blender/compositor/nodes/COM_GlareNode.cpp index 0429a1a80cf..7afe1510ae4 100644 --- a/source/blender/compositor/nodes/COM_GlareNode.cpp +++ b/source/blender/compositor/nodes/COM_GlareNode.cpp @@ -36,7 +36,7 @@ GlareNode::GlareNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void GlareNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void GlareNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *node = this->getbNode(); NodeGlare *glare = (NodeGlare *)node->storage; diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp index 003bc91edd3..e159886bb46 100644 --- a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp +++ b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp @@ -36,7 +36,7 @@ HueSaturationValueCorrectNode::HueSaturationValueCorrectNode(bNode *editorNode) /* pass */ } -void HueSaturationValueCorrectNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void HueSaturationValueCorrectNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *valueSocket = this->getInputSocket(0); NodeInput *colorSocket = this->getInputSocket(1); diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp b/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp index cdec1250c6e..29c296a896d 100644 --- a/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp +++ b/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp @@ -35,7 +35,7 @@ HueSaturationValueNode::HueSaturationValueNode(bNode *editorNode) : Node(editorN /* pass */ } -void HueSaturationValueNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void HueSaturationValueNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *valueSocket = this->getInputSocket(0); NodeInput *colorSocket = this->getInputSocket(1); diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp index e105f530eb2..facd422c217 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cpp +++ b/source/blender/compositor/nodes/COM_ImageNode.cpp @@ -32,6 +32,7 @@ #include "COM_SetValueOperation.h" #include "COM_SetVectorOperation.h" #include "COM_SetColorOperation.h" +#include "COM_SeparateColorNode.h" ImageNode::ImageNode(bNode *editorNode) : Node(editorNode) { @@ -39,19 +40,19 @@ ImageNode::ImageNode(bNode *editorNode) : Node(editorNode) } NodeOperation *ImageNode::doMultilayerCheck(NodeConverter &converter, RenderLayer *rl, Image *image, ImageUser *user, - int framenumber, int outputsocketIndex, int passindex, DataType datatype) const + int framenumber, int outputsocketIndex, int passindex, int view, DataType datatype) const { NodeOutput *outputSocket = this->getOutputSocket(outputsocketIndex); MultilayerBaseOperation *operation = NULL; switch (datatype) { case COM_DT_VALUE: - operation = new MultilayerValueOperation(passindex); + operation = new MultilayerValueOperation(passindex, view); break; case COM_DT_VECTOR: - operation = new MultilayerVectorOperation(passindex); + operation = new MultilayerVectorOperation(passindex, view); break; case COM_DT_COLOR: - operation = new MultilayerColorOperation(passindex); + operation = new MultilayerColorOperation(passindex, view); break; default: break; @@ -78,7 +79,6 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo int numberOfOutputs = this->getNumberOfOutputSockets(); bool outputStraightAlpha = (editorNode->custom1 & CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT) != 0; BKE_image_user_frame_calc(imageuser, context.getFramenumber(), 0); - /* force a load, we assume iuser index will be set OK anyway */ if (image && image->type == IMA_TYPE_MULTILAYER) { bool is_multilayer_ok = false; @@ -95,6 +95,9 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo NodeOperation *operation = NULL; socket = this->getOutputSocket(index); bNodeSocket *bnodeSocket = socket->getbNodeSocket(); + RenderPass *rpass = (RenderPass *)BLI_findstring(&rl->passes, bnodeSocket->identifier, offsetof(RenderPass, internal_name)); + int view = 0; + /* Passes in the file can differ from passes stored in sockets (#36755). * Look up the correct file pass using the socket identifier instead. */ @@ -103,35 +106,61 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo int passindex = storage->pass_index;*/ RenderPass *rpass = (RenderPass *)BLI_findlink(&rl->passes, passindex); #endif - int passindex; - RenderPass *rpass; - for (rpass = (RenderPass *)rl->passes.first, passindex = 0; rpass; rpass = rpass->next, ++passindex) - if (STREQ(rpass->name, bnodeSocket->identifier)) - break; + + /* returns the image view to use for the current active view */ + if (BLI_listbase_count_ex(&image->rr->views, 2) > 1) { + const int view_image = imageuser->view; + const bool is_allview = (view_image == 0); /* if view selected == All (0) */ + + if (is_allview) { + /* heuristic to match image name with scene names + * check if the view name exists in the image */ + view = BLI_findstringindex(&image->rr->views, context.getViewName(), offsetof(RenderView, name)); + if (view == -1) view = 0; + } + else { + view = view_image - 1; + } + } + if (rpass) { - imageuser->pass = passindex; + int passindex = BLI_findindex(&rl->passes, rpass); switch (rpass->channels) { case 1: - operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_VALUE); + operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, + passindex, view, COM_DT_VALUE); break; /* using image operations for both 3 and 4 channels (RGB and RGBA respectively) */ /* XXX any way to detect actual vector images? */ case 3: - operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_VECTOR); + operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, + passindex, view, COM_DT_VECTOR); break; case 4: - operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_COLOR); + operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, + passindex, view, COM_DT_COLOR); break; default: /* dummy operation is added below */ break; } - if (index == 0 && operation) { converter.addPreview(operation->getOutputSocket()); } + if (rpass->passtype == SCE_PASS_COMBINED) { + BLI_assert(operation != NULL); + BLI_assert(index < numberOfOutputs - 1); + NodeOutput *outputSocket = this->getOutputSocket(index + 1); + SeparateChannelOperation *separate_operation; + separate_operation = new SeparateChannelOperation(); + separate_operation->setChannel(3); + converter.addOperation(separate_operation); + converter.addLink(operation->getOutputSocket(), separate_operation->getInputSocket(0)); + converter.mapOutputSocket(outputSocket, separate_operation->getOutputSocket()); + index++; + } } - + /* incase we can't load the layer */ if (operation == NULL) converter.setInvalidOutput(getOutputSocket(index)); @@ -152,6 +181,8 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo operation->setImage(image); operation->setImageUser(imageuser); operation->setFramenumber(framenumber); + operation->setRenderData(context.getRenderData()); + operation->setViewName(context.getViewName()); converter.addOperation(operation); if (outputStraightAlpha) { @@ -174,6 +205,8 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo alphaOperation->setImage(image); alphaOperation->setImageUser(imageuser); alphaOperation->setFramenumber(framenumber); + alphaOperation->setRenderData(context.getRenderData()); + alphaOperation->setViewName(context.getViewName()); converter.addOperation(alphaOperation); converter.mapOutputSocket(alphaImage, alphaOperation->getOutputSocket()); @@ -184,6 +217,8 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo depthOperation->setImage(image); depthOperation->setImageUser(imageuser); depthOperation->setFramenumber(framenumber); + depthOperation->setRenderData(context.getRenderData()); + depthOperation->setViewName(context.getViewName()); converter.addOperation(depthOperation); converter.mapOutputSocket(depthImage, depthOperation->getOutputSocket()); @@ -223,6 +258,7 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo } if (operation) { + /* not supporting multiview for this generic case */ converter.addOperation(operation); converter.mapOutputSocket(output, operation->getOutputSocket()); } diff --git a/source/blender/compositor/nodes/COM_ImageNode.h b/source/blender/compositor/nodes/COM_ImageNode.h index 1daa39a2a1f..267794510e1 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.h +++ b/source/blender/compositor/nodes/COM_ImageNode.h @@ -36,7 +36,7 @@ extern "C" { class ImageNode : public Node { private: NodeOperation *doMultilayerCheck(NodeConverter &converter, RenderLayer *rl, Image *image, ImageUser *user, - int framenumber, int outputsocketIndex, int passindex, DataType datatype) const; + int framenumber, int outputsocketIndex, int passtype, int view, DataType datatype) const; public: ImageNode(bNode *editorNode); void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; diff --git a/source/blender/compositor/nodes/COM_InpaintNode.cpp b/source/blender/compositor/nodes/COM_InpaintNode.cpp index 1371cdb5f1d..9e78625684d 100644 --- a/source/blender/compositor/nodes/COM_InpaintNode.cpp +++ b/source/blender/compositor/nodes/COM_InpaintNode.cpp @@ -31,7 +31,7 @@ InpaintNode::InpaintNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void InpaintNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void InpaintNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *editorNode = this->getbNode(); diff --git a/source/blender/compositor/nodes/COM_InvertNode.cpp b/source/blender/compositor/nodes/COM_InvertNode.cpp index ed4a21132ca..da499d66c2c 100644 --- a/source/blender/compositor/nodes/COM_InvertNode.cpp +++ b/source/blender/compositor/nodes/COM_InvertNode.cpp @@ -30,7 +30,7 @@ InvertNode::InvertNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void InvertNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void InvertNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { InvertOperation *operation = new InvertOperation(); bNode *node = this->getbNode(); diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp index 32db452e6c2..3d3cc841715 100644 --- a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp +++ b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp @@ -30,7 +30,7 @@ LensDistortionNode::LensDistortionNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void LensDistortionNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void LensDistortionNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *editorNode = this->getbNode(); NodeLensDist *data = (NodeLensDist *)editorNode->storage; diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp b/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp index e23ec243ff4..382296a7f3a 100644 --- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp @@ -30,7 +30,7 @@ LuminanceMatteNode::LuminanceMatteNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void LuminanceMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void LuminanceMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *editorsnode = getbNode(); NodeInput *inputSocket = this->getInputSocket(0); diff --git a/source/blender/compositor/nodes/COM_MapRangeNode.cpp b/source/blender/compositor/nodes/COM_MapRangeNode.cpp index 2c164cfad32..148ca00205c 100644 --- a/source/blender/compositor/nodes/COM_MapRangeNode.cpp +++ b/source/blender/compositor/nodes/COM_MapRangeNode.cpp @@ -30,7 +30,7 @@ MapRangeNode::MapRangeNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void MapRangeNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void MapRangeNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *valueSocket = this->getInputSocket(0); NodeInput *sourceMinSocket = this->getInputSocket(1); diff --git a/source/blender/compositor/nodes/COM_MapUVNode.cpp b/source/blender/compositor/nodes/COM_MapUVNode.cpp index 25ca7b8b8c6..ec38e23ec07 100644 --- a/source/blender/compositor/nodes/COM_MapUVNode.cpp +++ b/source/blender/compositor/nodes/COM_MapUVNode.cpp @@ -28,7 +28,7 @@ MapUVNode::MapUVNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void MapUVNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void MapUVNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bNode *node = this->getbNode(); diff --git a/source/blender/compositor/nodes/COM_MapValueNode.cpp b/source/blender/compositor/nodes/COM_MapValueNode.cpp index d7ee4e6a38b..f04c6a2d316 100644 --- a/source/blender/compositor/nodes/COM_MapValueNode.cpp +++ b/source/blender/compositor/nodes/COM_MapValueNode.cpp @@ -30,7 +30,7 @@ MapValueNode::MapValueNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void MapValueNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void MapValueNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { TexMapping *storage = (TexMapping *)this->getbNode()->storage; diff --git a/source/blender/compositor/nodes/COM_MathNode.cpp b/source/blender/compositor/nodes/COM_MathNode.cpp index ef7046b8165..eb6bb2caf56 100644 --- a/source/blender/compositor/nodes/COM_MathNode.cpp +++ b/source/blender/compositor/nodes/COM_MathNode.cpp @@ -24,66 +24,66 @@ #include "COM_MathBaseOperation.h" #include "COM_ExecutionSystem.h" -void MathNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void MathNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { MathBaseOperation *operation = NULL; switch (this->getbNode()->custom1) { - case 0: /* Add */ + case NODE_MATH_ADD: operation = new MathAddOperation(); break; - case 1: /* Subtract */ + case NODE_MATH_SUB: operation = new MathSubtractOperation(); break; - case 2: /* Multiply */ + case NODE_MATH_MUL: operation = new MathMultiplyOperation(); break; - case 3: /* Divide */ + case NODE_MATH_DIVIDE: operation = new MathDivideOperation(); break; - case 4: /* Sine */ + case NODE_MATH_SIN: operation = new MathSineOperation(); break; - case 5: /* Cosine */ + case NODE_MATH_COS: operation = new MathCosineOperation(); break; - case 6: /* Tangent */ + case NODE_MATH_TAN: operation = new MathTangentOperation(); break; - case 7: /* Arc-Sine */ + case NODE_MATH_ASIN: operation = new MathArcSineOperation(); break; - case 8: /* Arc-Cosine */ + case NODE_MATH_ACOS: operation = new MathArcCosineOperation(); break; - case 9: /* Arc-Tangent */ + case NODE_MATH_ATAN: operation = new MathArcTangentOperation(); break; - case 10: /* Power */ + case NODE_MATH_POW: operation = new MathPowerOperation(); break; - case 11: /* Logarithm */ + case NODE_MATH_LOG: operation = new MathLogarithmOperation(); break; - case 12: /* Minimum */ + case NODE_MATH_MIN: operation = new MathMinimumOperation(); break; - case 13: /* Maximum */ + case NODE_MATH_MAX: operation = new MathMaximumOperation(); break; - case 14: /* Round */ + case NODE_MATH_ROUND: operation = new MathRoundOperation(); break; - case 15: /* Less Than */ + case NODE_MATH_LESS: operation = new MathLessThanOperation(); break; - case 16: /* Greater Than */ + case NODE_MATH_GREATER: operation = new MathGreaterThanOperation(); break; - case 17: /* Modulo */ + case NODE_MATH_MOD: operation = new MathModuloOperation(); break; - case 18: /* Absolute Value */ + case NODE_MATH_ABS: operation = new MathAbsoluteOperation(); break; } diff --git a/source/blender/compositor/nodes/COM_MixNode.cpp b/source/blender/compositor/nodes/COM_MixNode.cpp index b12dfc02ed7..0607d6d6705 100644 --- a/source/blender/compositor/nodes/COM_MixNode.cpp +++ b/source/blender/compositor/nodes/COM_MixNode.cpp @@ -34,15 +34,15 @@ MixNode::MixNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void MixNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void MixNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *valueSocket = this->getInputSocket(0); NodeInput *color1Socket = this->getInputSocket(1); NodeInput *color2Socket = this->getInputSocket(2); NodeOutput *outputSocket = this->getOutputSocket(0); bNode *editorNode = this->getbNode(); - bool useAlphaPremultiply = this->getbNode()->custom2 & 1; - bool useClamp = this->getbNode()->custom2 & 2; + bool useAlphaPremultiply = (this->getbNode()->custom2 & 1) != 0; + bool useClamp = (this->getbNode()->custom2 & 2) != 0; MixBaseOperation *convertProg; switch (editorNode->custom1) { diff --git a/source/blender/compositor/nodes/COM_NormalNode.cpp b/source/blender/compositor/nodes/COM_NormalNode.cpp index d7c3fd11844..26da61cb9e7 100644 --- a/source/blender/compositor/nodes/COM_NormalNode.cpp +++ b/source/blender/compositor/nodes/COM_NormalNode.cpp @@ -31,7 +31,7 @@ NormalNode::NormalNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void NormalNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void NormalNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *inputSocket = this->getInputSocket(0); NodeOutput *outputSocket = this->getOutputSocket(0); diff --git a/source/blender/compositor/nodes/COM_NormalizeNode.cpp b/source/blender/compositor/nodes/COM_NormalizeNode.cpp index f6e919c168f..a13fcd2a301 100644 --- a/source/blender/compositor/nodes/COM_NormalizeNode.cpp +++ b/source/blender/compositor/nodes/COM_NormalizeNode.cpp @@ -28,7 +28,7 @@ NormalizeNode::NormalizeNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void NormalizeNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void NormalizeNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NormalizeOperation *operation = new NormalizeOperation(); converter.addOperation(operation); diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.cpp b/source/blender/compositor/nodes/COM_OutputFileNode.cpp index 92fa74b9a2e..42805d1ff37 100644 --- a/source/blender/compositor/nodes/COM_OutputFileNode.cpp +++ b/source/blender/compositor/nodes/COM_OutputFileNode.cpp @@ -23,8 +23,11 @@ #include "COM_OutputFileNode.h" #include "COM_OutputFileOperation.h" +#include "COM_OutputFileMultiViewOperation.h" #include "COM_ExecutionSystem.h" +#include "BKE_scene.h" + #include "BLI_path_util.h" OutputFileNode::OutputFileNode(bNode *editorNode) : Node(editorNode) @@ -35,6 +38,7 @@ OutputFileNode::OutputFileNode(bNode *editorNode) : Node(editorNode) void OutputFileNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const { NodeImageMultiFile *storage = (NodeImageMultiFile *)this->getbNode()->storage; + const bool is_multiview = (context.getRenderData()->scemode & R_MULTIVIEW) != 0; if (!context.isRendering()) { /* only output files when rendering a sequence - @@ -43,13 +47,24 @@ void OutputFileNode::convertToOperations(NodeConverter &converter, const Composi */ return; } - + if (storage->format.imtype == R_IMF_IMTYPE_MULTILAYER) { + const bool use_half_float = (storage->format.depth == R_IMF_CHAN_DEPTH_16); /* single output operation for the multilayer file */ - OutputOpenExrMultiLayerOperation *outputOperation = new OutputOpenExrMultiLayerOperation( - context.getRenderData(), context.getbNodeTree(), storage->base_path, storage->format.exr_codec); + OutputOpenExrMultiLayerOperation *outputOperation; + + if (is_multiview && storage->format.views_format == R_IMF_VIEWS_MULTIVIEW) { + outputOperation = new OutputOpenExrMultiLayerMultiViewOperation( + context.getRenderData(), context.getbNodeTree(), storage->base_path, + storage->format.exr_codec, use_half_float, context.getViewName()); + } + else { + outputOperation = new OutputOpenExrMultiLayerOperation( + context.getRenderData(), context.getbNodeTree(), storage->base_path, + storage->format.exr_codec, use_half_float, context.getViewName()); + } converter.addOperation(outputOperation); - + int num_inputs = getNumberOfInputSockets(); bool previewAdded = false; for (int i = 0; i < num_inputs; ++i) { @@ -76,17 +91,31 @@ void OutputFileNode::convertToOperations(NodeConverter &converter, const Composi NodeImageMultiFileSocket *sockdata = (NodeImageMultiFileSocket *)input->getbNodeSocket()->storage; ImageFormatData *format = (sockdata->use_node_format ? &storage->format : &sockdata->format); char path[FILE_MAX]; - + /* combine file path for the input */ BLI_join_dirfile(path, FILE_MAX, storage->base_path, sockdata->path); - - OutputSingleLayerOperation *outputOperation = new OutputSingleLayerOperation( - context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path, - context.getViewSettings(), context.getDisplaySettings()); + + NodeOperation *outputOperation = NULL; + + if (is_multiview && format->views_format == R_IMF_VIEWS_MULTIVIEW) { + outputOperation = new OutputOpenExrSingleLayerMultiViewOperation( + context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path, + context.getViewSettings(), context.getDisplaySettings(), context.getViewName()); + } + else if ((!is_multiview) || (format->views_format == R_IMF_VIEWS_INDIVIDUAL)) { + outputOperation = new OutputSingleLayerOperation( + context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path, + context.getViewSettings(), context.getDisplaySettings(), context.getViewName()); + } + else { /* R_IMF_VIEWS_STEREO_3D */ + outputOperation = new OutputStereoOperation( + context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path, + sockdata->layer, context.getViewSettings(), context.getDisplaySettings(), context.getViewName()); + } + converter.addOperation(outputOperation); - converter.mapInputSocket(input, outputOperation->getInputSocket(0)); - + if (!previewAdded) { converter.addNodeInputPreview(input); previewAdded = true; diff --git a/source/blender/compositor/nodes/COM_PixelateNode.cpp b/source/blender/compositor/nodes/COM_PixelateNode.cpp index da3cd74e771..fe806dbf307 100644 --- a/source/blender/compositor/nodes/COM_PixelateNode.cpp +++ b/source/blender/compositor/nodes/COM_PixelateNode.cpp @@ -30,7 +30,7 @@ PixelateNode::PixelateNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void PixelateNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void PixelateNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *inputSocket = this->getInputSocket(0); NodeOutput *outputSocket = this->getOutputSocket(0); diff --git a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp index 9b69bc5a46e..379b9f193e8 100644 --- a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp +++ b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp @@ -54,6 +54,10 @@ void PlaneTrackDeformNode::convertToOperations(NodeConverter &converter, const C warp_image_operation->setTrackingObject(data->tracking_object); warp_image_operation->setPlaneTrackName(data->plane_track_name); warp_image_operation->setFramenumber(frame_number); + if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) { + warp_image_operation->setMotionBlurSamples(data->motion_blur_samples); + warp_image_operation->setMotionBlurShutter(data->motion_blur_shutter); + } converter.addOperation(warp_image_operation); converter.mapInputSocket(input_image, warp_image_operation->getInputSocket(0)); @@ -64,6 +68,10 @@ void PlaneTrackDeformNode::convertToOperations(NodeConverter &converter, const C plane_mask_operation->setTrackingObject(data->tracking_object); plane_mask_operation->setPlaneTrackName(data->plane_track_name); plane_mask_operation->setFramenumber(frame_number); + if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) { + plane_mask_operation->setMotionBlurSamples(data->motion_blur_samples); + plane_mask_operation->setMotionBlurShutter(data->motion_blur_shutter); + } converter.addOperation(plane_mask_operation); converter.mapOutputSocket(output_plane, plane_mask_operation->getOutputSocket()); diff --git a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h index 71e6ab12dfc..653100ce6a4 100644 --- a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h +++ b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h @@ -20,7 +20,6 @@ */ #include "COM_Node.h" -#include "DNA_node_types.h" extern "C" { # include "DNA_movieclip_types.h" diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp index cc66c688379..842edcf35c9 100644 --- a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp +++ b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp @@ -27,6 +27,10 @@ #include "COM_ScaleOperation.h" #include "COM_SetValueOperation.h" +#ifdef WITH_CYCLES_DEBUG +# include "RE_pipeline.h" +#endif + RenderLayersNode::RenderLayersNode(bNode *editorNode) : Node(editorNode) { /* pass */ @@ -42,7 +46,8 @@ void RenderLayersNode::testSocketLink(NodeConverter &converter, const Compositor operation->setScene(scene); operation->setLayerId(layerId); operation->setRenderData(context.getRenderData()); - + operation->setViewName(context.getViewName()); + converter.mapOutputSocket(outputSocket, operation->getOutputSocket()); converter.addOperation(operation); @@ -85,4 +90,13 @@ void RenderLayersNode::convertToOperations(NodeConverter &converter, const Compo testSocketLink(converter, context, 28, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_DIRECT)); testSocketLink(converter, context, 29, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_INDIRECT)); testSocketLink(converter, context, 30, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_COLOR)); + +#ifdef WITH_CYCLES_DEBUG + { + Scene *scene = (Scene *)this->getbNode()->id; + Render *re = RE_GetRender(scene->id.name); + int debug_pass_type = ((re != NULL) ? RE_debug_pass_type_get(re) : scene->r.debug_pass_type); + testSocketLink(converter, context, 31, new RenderLayersCyclesDebugOperation(SCE_PASS_DEBUG, debug_pass_type)); + } +#endif } diff --git a/source/blender/compositor/nodes/COM_RotateNode.cpp b/source/blender/compositor/nodes/COM_RotateNode.cpp index c5fe88b3636..6fd7e357775 100644 --- a/source/blender/compositor/nodes/COM_RotateNode.cpp +++ b/source/blender/compositor/nodes/COM_RotateNode.cpp @@ -31,7 +31,7 @@ RotateNode::RotateNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void RotateNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void RotateNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *inputSocket = this->getInputSocket(0); NodeInput *inputDegreeSocket = this->getInputSocket(1); diff --git a/source/blender/compositor/nodes/COM_SeparateColorNode.cpp b/source/blender/compositor/nodes/COM_SeparateColorNode.cpp index a6fa9065364..780ce73d340 100644 --- a/source/blender/compositor/nodes/COM_SeparateColorNode.cpp +++ b/source/blender/compositor/nodes/COM_SeparateColorNode.cpp @@ -96,17 +96,17 @@ void SeparateColorNode::convertToOperations(NodeConverter &converter, const Comp } -NodeOperation *SeparateRGBANode::getColorConverter(const CompositorContext &context) const +NodeOperation *SeparateRGBANode::getColorConverter(const CompositorContext &/*context*/) const { return NULL; /* no conversion needed */ } -NodeOperation *SeparateHSVANode::getColorConverter(const CompositorContext &context) const +NodeOperation *SeparateHSVANode::getColorConverter(const CompositorContext &/*context*/) const { return new ConvertRGBToHSVOperation(); } -NodeOperation *SeparateYCCANode::getColorConverter(const CompositorContext &context) const +NodeOperation *SeparateYCCANode::getColorConverter(const CompositorContext &/*context*/) const { ConvertRGBToYCCOperation *operation = new ConvertRGBToYCCOperation(); bNode *editorNode = this->getbNode(); @@ -114,7 +114,7 @@ NodeOperation *SeparateYCCANode::getColorConverter(const CompositorContext &cont return operation; } -NodeOperation *SeparateYUVANode::getColorConverter(const CompositorContext &context) const +NodeOperation *SeparateYUVANode::getColorConverter(const CompositorContext &/*context*/) const { return new ConvertRGBToYUVOperation(); } diff --git a/source/blender/compositor/nodes/COM_SetAlphaNode.cpp b/source/blender/compositor/nodes/COM_SetAlphaNode.cpp index 22ddd5bb157..32c03c695be 100644 --- a/source/blender/compositor/nodes/COM_SetAlphaNode.cpp +++ b/source/blender/compositor/nodes/COM_SetAlphaNode.cpp @@ -24,7 +24,7 @@ #include "COM_SetAlphaOperation.h" #include "COM_ExecutionSystem.h" -void SetAlphaNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void SetAlphaNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { SetAlphaOperation *operation = new SetAlphaOperation(); diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp index 48c8acfc6a1..465a94e8335 100644 --- a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp +++ b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp @@ -46,7 +46,7 @@ SocketProxyNode::SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bN this->addOutputSocket(dt, editorOutput); } -void SocketProxyNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void SocketProxyNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeOperationOutput *proxy_output = converter.addInputProxy(getInputSocket(0), m_use_conversion); converter.mapOutputSocket(getOutputSocket(), proxy_output); @@ -68,13 +68,14 @@ SocketBufferNode::SocketBufferNode(bNode *editorNode, bNodeSocket *editorInput, this->addOutputSocket(dt, editorOutput); } -void SocketBufferNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void SocketBufferNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeOutput *output = this->getOutputSocket(0); NodeInput *input = this->getInputSocket(0); - WriteBufferOperation *writeOperation = new WriteBufferOperation(); - ReadBufferOperation *readOperation = new ReadBufferOperation(); + DataType datatype = output->getDataType(); + WriteBufferOperation *writeOperation = new WriteBufferOperation(datatype); + ReadBufferOperation *readOperation = new ReadBufferOperation(datatype); readOperation->setMemoryProxy(writeOperation->getMemoryProxy()); converter.addOperation(writeOperation); converter.addOperation(readOperation); diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp index 15eca0a97e5..0f917d317f9 100644 --- a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp @@ -22,6 +22,8 @@ #include "COM_SplitViewerNode.h" #include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_scene.h" #include "COM_SplitOperation.h" #include "COM_ViewerOperation.h" @@ -55,6 +57,8 @@ void SplitViewerNode::convertToOperations(NodeConverter &converter, const Compos viewerOperation->setImageUser(imageUser); viewerOperation->setViewSettings(context.getViewSettings()); viewerOperation->setDisplaySettings(context.getDisplaySettings()); + viewerOperation->setRenderData(context.getRenderData()); + viewerOperation->setViewName(context.getViewName()); /* defaults - the viewer node has these options but not exposed for split view * we could use the split to define an area of interest on one axis at least */ diff --git a/source/blender/compositor/nodes/COM_SunBeamsNode.cpp b/source/blender/compositor/nodes/COM_SunBeamsNode.cpp index ed14acabf36..7cf3c90c786 100644 --- a/source/blender/compositor/nodes/COM_SunBeamsNode.cpp +++ b/source/blender/compositor/nodes/COM_SunBeamsNode.cpp @@ -27,7 +27,7 @@ SunBeamsNode::SunBeamsNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void SunBeamsNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void SunBeamsNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *inputSocket = this->getInputSocket(0); NodeOutput *outputSocket = this->getOutputSocket(0); diff --git a/source/blender/compositor/nodes/COM_SwitchNode.cpp b/source/blender/compositor/nodes/COM_SwitchNode.cpp index 10f0ee3821d..eb854983d4c 100644 --- a/source/blender/compositor/nodes/COM_SwitchNode.cpp +++ b/source/blender/compositor/nodes/COM_SwitchNode.cpp @@ -27,7 +27,7 @@ SwitchNode::SwitchNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void SwitchNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void SwitchNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { bool condition = this->getbNode()->custom1; diff --git a/source/blender/compositor/nodes/COM_SwitchViewNode.cpp b/source/blender/compositor/nodes/COM_SwitchViewNode.cpp new file mode 100644 index 00000000000..5a23b8b4d9e --- /dev/null +++ b/source/blender/compositor/nodes/COM_SwitchViewNode.cpp @@ -0,0 +1,42 @@ +/* + * Copyright 2015, 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: + * Dalai Felinto + */ + +#include "COM_SwitchViewNode.h" +#include "BLI_listbase.h" + +SwitchViewNode::SwitchViewNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} + +void SwitchViewNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +{ + NodeOperationOutput *result; + const char *viewName = context.getViewName(); + bNode *bnode = this->getbNode(); + + /* get the internal index of the socket with a matching name */ + int nr = BLI_findstringindex(&bnode->inputs, viewName, offsetof(bNodeSocket, name)); + nr = max(nr, 0); + + result = converter.addInputProxy(getInputSocket(nr), false); + converter.mapOutputSocket(getOutputSocket(0), result); +} diff --git a/source/blender/compositor/intern/COM_ChannelInfo.cpp b/source/blender/compositor/nodes/COM_SwitchViewNode.h index 557075cdc80..6ab5145bed5 100644 --- a/source/blender/compositor/intern/COM_ChannelInfo.cpp +++ b/source/blender/compositor/nodes/COM_SwitchViewNode.h @@ -1,5 +1,5 @@ /* - * Copyright 2011, Blender Foundation. + * Copyright 2015, Blender Foundation. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -15,21 +15,23 @@ * 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 + * Contributor: + * Dalai Felinto */ -#include "COM_ChannelInfo.h" -#include "COM_defines.h" -#include <stdio.h> +#ifndef _COM_SwitchViewNode_h_ +#define _COM_SwitchViewNode_h_ +#include "COM_Node.h" +#include "COM_NodeOperation.h" +#include "DNA_node_types.h" /** - * @brief create new ChannelInfo instance and sets the defaults. + * @brief SwitchViewNode + * @ingroup Node */ -ChannelInfo::ChannelInfo() -{ - this->m_number = 0; - this->m_premultiplied = true; - this->m_type = COM_CT_UNUSED; -} +class SwitchViewNode : public Node { +public: + SwitchViewNode(bNode *editorNode); + void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; +}; +#endif diff --git a/source/blender/compositor/nodes/COM_TextureNode.cpp b/source/blender/compositor/nodes/COM_TextureNode.cpp index 2ac027ca326..b80ca2fcdbd 100644 --- a/source/blender/compositor/nodes/COM_TextureNode.cpp +++ b/source/blender/compositor/nodes/COM_TextureNode.cpp @@ -35,7 +35,7 @@ void TextureNode::convertToOperations(NodeConverter &converter, const Compositor Tex *texture = (Tex *)editorNode->id; TextureOperation *operation = new TextureOperation(); const ColorManagedDisplaySettings *displaySettings = context.getDisplaySettings(); - bool sceneColorManage = strcmp(displaySettings->display_device, "None") != 0; + bool sceneColorManage = !STREQ(displaySettings->display_device, "None"); operation->setTexture(texture); operation->setRenderData(context.getRenderData()); operation->setSceneColorManage(sceneColorManage); diff --git a/source/blender/compositor/nodes/COM_TonemapNode.cpp b/source/blender/compositor/nodes/COM_TonemapNode.cpp index 5ac73b9f9c2..961139d4855 100644 --- a/source/blender/compositor/nodes/COM_TonemapNode.cpp +++ b/source/blender/compositor/nodes/COM_TonemapNode.cpp @@ -29,7 +29,7 @@ TonemapNode::TonemapNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void TonemapNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void TonemapNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeTonemap *data = (NodeTonemap *)this->getbNode()->storage; diff --git a/source/blender/compositor/nodes/COM_TransformNode.cpp b/source/blender/compositor/nodes/COM_TransformNode.cpp index f1d5771bab3..148409a6427 100644 --- a/source/blender/compositor/nodes/COM_TransformNode.cpp +++ b/source/blender/compositor/nodes/COM_TransformNode.cpp @@ -33,7 +33,7 @@ TransformNode::TransformNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void TransformNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void TransformNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *imageInput = this->getInputSocket(0); NodeInput *xInput = this->getInputSocket(1); diff --git a/source/blender/compositor/nodes/COM_TranslateNode.cpp b/source/blender/compositor/nodes/COM_TranslateNode.cpp index 990cbe19be2..04dc1d435d3 100644 --- a/source/blender/compositor/nodes/COM_TranslateNode.cpp +++ b/source/blender/compositor/nodes/COM_TranslateNode.cpp @@ -57,8 +57,8 @@ void TranslateNode::convertToOperations(NodeConverter &converter, const Composit converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0)); if (data->wrap_axis) { - WriteBufferOperation *writeOperation = new WriteBufferOperation(); - WrapOperation *wrapOperation = new WrapOperation(); + WriteBufferOperation *writeOperation = new WriteBufferOperation(COM_DT_COLOR); + WrapOperation *wrapOperation = new WrapOperation(COM_DT_COLOR); wrapOperation->setMemoryProxy(writeOperation->getMemoryProxy()); wrapOperation->setWrapping(data->wrap_axis); diff --git a/source/blender/compositor/nodes/COM_ValueNode.cpp b/source/blender/compositor/nodes/COM_ValueNode.cpp index 62a312da67c..c75d9296807 100644 --- a/source/blender/compositor/nodes/COM_ValueNode.cpp +++ b/source/blender/compositor/nodes/COM_ValueNode.cpp @@ -29,7 +29,7 @@ ValueNode::ValueNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void ValueNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ValueNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { SetValueOperation *operation = new SetValueOperation(); NodeOutput *output = this->getOutputSocket(0); diff --git a/source/blender/compositor/nodes/COM_VectorCurveNode.cpp b/source/blender/compositor/nodes/COM_VectorCurveNode.cpp index 197b2c8bd0c..7222a018fa0 100644 --- a/source/blender/compositor/nodes/COM_VectorCurveNode.cpp +++ b/source/blender/compositor/nodes/COM_VectorCurveNode.cpp @@ -29,7 +29,7 @@ VectorCurveNode::VectorCurveNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void VectorCurveNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void VectorCurveNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { VectorCurveOperation *operation = new VectorCurveOperation(); operation->setCurveMapping((CurveMapping *)this->getbNode()->storage); diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp index 30f51794e8d..06f12ccc559 100644 --- a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp @@ -31,7 +31,7 @@ ViewLevelsNode::ViewLevelsNode(bNode *editorNode) : Node(editorNode) /* pass */ } -void ViewLevelsNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +void ViewLevelsNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const { NodeInput *input = this->getInputSocket(0); if (input->isLinked()) { diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp index 07aa960c4d9..ab819ce6e30 100644 --- a/source/blender/compositor/nodes/COM_ViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp @@ -22,6 +22,9 @@ #include "COM_ViewerNode.h" #include "BKE_global.h" +#include "BKE_image.h" +#include "BLI_listbase.h" +#include "BKE_scene.h" #include "COM_ViewerOperation.h" #include "COM_ExecutionSystem.h" @@ -35,7 +38,7 @@ void ViewerNode::convertToOperations(NodeConverter &converter, const CompositorC { bNode *editorNode = this->getbNode(); bool do_output = (editorNode->flag & NODE_DO_OUTPUT_RECALC || context.isRendering()) && (editorNode->flag & NODE_DO_OUTPUT); - bool ignore_alpha = editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA; + bool ignore_alpha = (editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA) != 0; NodeInput *imageSocket = this->getInputSocket(0); NodeInput *alphaSocket = this->getInputSocket(1); @@ -51,6 +54,8 @@ void ViewerNode::convertToOperations(NodeConverter &converter, const CompositorC viewerOperation->setCenterY(editorNode->custom4); /* alpha socket gives either 1 or a custom alpha value if "use alpha" is enabled */ viewerOperation->setUseAlphaInput(ignore_alpha || alphaSocket->isLinked()); + viewerOperation->setRenderData(context.getRenderData()); + viewerOperation->setViewName(context.getViewName()); viewerOperation->setViewSettings(context.getViewSettings()); viewerOperation->setDisplaySettings(context.getDisplaySettings()); diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp index 995c61589cc..2e60c2d3e42 100644 --- a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp @@ -45,7 +45,7 @@ void AntiAliasOperation::initExecution() NodeOperation::initMutex(); } -void AntiAliasOperation::executePixel(float output[4], int x, int y, void *data) +void AntiAliasOperation::executePixel(float output[4], int x, int y, void * /*data*/) { if (y < 0 || (unsigned int)y >= this->m_height || x < 0 || (unsigned int)x >= this->m_width) { output[0] = 0.0f; @@ -66,7 +66,7 @@ void AntiAliasOperation::deinitExecution() NodeOperation::deinitMutex(); } -bool AntiAliasOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool AntiAliasOperation::determineDependingAreaOfInterest(rcti * /*input*/, ReadBufferOperation *readOperation, rcti *output) { rcti imageInput; if (this->m_buffer) { @@ -95,7 +95,7 @@ void *AntiAliasOperation::initializeTileData(rcti *rect) float *input = tile->getBuffer(); char *valuebuffer = (char *)MEM_mallocN(sizeof(char) * size, __func__); for (int i = 0; i < size; i++) { - float in = input[i * COM_NUMBER_OF_CHANNELS]; + float in = input[i]; valuebuffer[i] = FTOCHAR(in); } antialias_tagbuf(tile->getWidth(), tile->getHeight(), valuebuffer); diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp b/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp index 2527f13c3ed..b24e48f52bc 100644 --- a/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp @@ -65,6 +65,10 @@ void BilateralBlurOperation::executePixel(float output[4], int x, int y, void *d zero_v4(blurColor); blurDivider = 0.0f; + /* TODO(sergey): This isn't really good bilateral filter, it should be + * using gaussian bell for weights. Also sigma_color doesn't seem to be + * used correct at all. + */ for (int yi = miny; yi < maxy; yi += QualityStepHelper::getStep()) { for (int xi = minx; xi < maxx; xi += QualityStepHelper::getStep()) { // read determinator diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp index d5aafc7c2ae..ce42de7a149 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp @@ -92,7 +92,7 @@ float *BlurBaseOperation::make_gausstab(float rad, int size) } #ifdef __SSE2__ -__m128 *BlurBaseOperation::convert_gausstab_sse(const float *gausstab, float rad, int size) +__m128 *BlurBaseOperation::convert_gausstab_sse(const float *gausstab, int size) { int n = 2 * size + 1; __m128 *gausstab_sse = (__m128 *) MEM_mallocN_aligned(sizeof(__m128) * n, 16, "gausstab sse"); @@ -133,6 +133,9 @@ float *BlurBaseOperation::make_dist_fac_inverse(float rad, int size, int falloff case PROP_SHARP: val = val * val; break; + case PROP_INVSQUARE: + val = val * (2.0f - val); + break; case PROP_LIN: /* fall-through */ #ifndef NDEBUG diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.h b/source/blender/compositor/operations/COM_BlurBaseOperation.h index e97dd4d766d..f9f37479c56 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.h +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.h @@ -39,7 +39,7 @@ protected: BlurBaseOperation(DataType data_type); float *make_gausstab(float rad, int size); #ifdef __SSE2__ - __m128 *convert_gausstab_sse(const float *gaustab, float rad, int size); + __m128 *convert_gausstab_sse(const float *gaustab, int size); #endif float *make_dist_fac_inverse(float rad, int size, int falloff); diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp index f5bca5371e6..189483708b5 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp @@ -45,7 +45,7 @@ BokehBlurOperation::BokehBlurOperation() : NodeOperation() this->m_inputBoundingBoxReader = NULL; } -void *BokehBlurOperation::initializeTileData(rcti *rect) +void *BokehBlurOperation::initializeTileData(rcti * /*rect*/) { lockMutex(); if (!this->m_sizeavailable) { @@ -110,11 +110,11 @@ void BokehBlurOperation::executePixel(float output[4], int x, int y, void *data) int step = getStep(); - int offsetadd = getOffsetAdd(); + int offsetadd = getOffsetAdd() * COM_NUM_CHANNELS_COLOR; float m = this->m_bokehDimension / pixelSize; for (int ny = miny; ny < maxy; ny += step) { - int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth); + int bufferindex = ((minx - bufferstartx) * COM_NUM_CHANNELS_COLOR) + ((ny - bufferstarty) * COM_NUM_CHANNELS_COLOR * bufferwidth); for (int nx = minx; nx < maxx; nx += step) { float u = this->m_bokehMidX - (nx - x) * m; float v = this->m_bokehMidY - (ny - y) * m; @@ -194,7 +194,7 @@ bool BokehBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffe void BokehBlurOperation::executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, - list<cl_kernel> *clKernelsToCleanUp) + list<cl_kernel> * /*clKernelsToCleanUp*/) { cl_kernel kernel = device->COM_clCreateKernel("bokehBlurKernel", NULL); if (!this->m_sizeavailable) { diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.cpp b/source/blender/compositor/operations/COM_BokehImageOperation.cpp index 6617fc62ab8..18846f2a2c5 100644 --- a/source/blender/compositor/operations/COM_BokehImageOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehImageOperation.cpp @@ -85,7 +85,7 @@ float BokehImageOperation::isInsideBokeh(float distance, float x, float y) } return insideBokeh; } -void BokehImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void BokehImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { float shift = this->m_data->lensshift; float shift2 = shift / 2.0f; @@ -116,7 +116,7 @@ void BokehImageOperation::deinitExecution() } } -void BokehImageOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) +void BokehImageOperation::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2]) { resolution[0] = COM_BLUR_BOKEH_PIXELS; resolution[1] = COM_BLUR_BOKEH_PIXELS; diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp b/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp index a2954a20e90..d26dcd17750 100644 --- a/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp +++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp @@ -24,7 +24,9 @@ #include "BLI_math.h" #include "BLI_utildefines.h" - +extern "C" { +#include "IMB_colormanagement.h" +} CalculateMeanOperation::CalculateMeanOperation() : NodeOperation() { @@ -42,7 +44,9 @@ void CalculateMeanOperation::initExecution() NodeOperation::initMutex(); } -void CalculateMeanOperation::executePixel(float output[4], int x, int y, void *data) +void CalculateMeanOperation::executePixel(float output[4], + int /*x*/, int /*y*/, + void * /*data*/) { output[0] = this->m_result; } @@ -53,7 +57,7 @@ void CalculateMeanOperation::deinitExecution() NodeOperation::deinitMutex(); } -bool CalculateMeanOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool CalculateMeanOperation::determineDependingAreaOfInterest(rcti * /*input*/, ReadBufferOperation *readOperation, rcti *output) { rcti imageInput; if (this->m_iscalculated) { @@ -96,7 +100,7 @@ void CalculateMeanOperation::calculateMean(MemoryBuffer *tile) switch (this->m_setting) { case 1: { - sum += rgb_to_bw(&buffer[offset]); + sum += IMB_colormanagement_get_luminance(&buffer[offset]); break; } case 2: diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp index 0c67da2d552..6b238e53d7b 100644 --- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp +++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp @@ -24,14 +24,18 @@ #include "BLI_math.h" #include "BLI_utildefines.h" - +extern "C" { +#include "IMB_colormanagement.h" +} CalculateStandardDeviationOperation::CalculateStandardDeviationOperation() : CalculateMeanOperation() { /* pass */ } -void CalculateStandardDeviationOperation::executePixel(float output[4], int x, int y, void *data) +void CalculateStandardDeviationOperation::executePixel(float output[4], + int /*x*/, int /*y*/, + void * /*data*/) { output[0] = this->m_standardDeviation; } @@ -55,7 +59,7 @@ void *CalculateStandardDeviationOperation::initializeTileData(rcti *rect) switch (this->m_setting) { case 1: /* rgb combined */ { - float value = rgb_to_bw(&buffer[offset]); + float value = IMB_colormanagement_get_luminance(&buffer[offset]); sum += (value - mean) * (value - mean); break; } diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp index 3329093882d..9a20ca412e0 100644 --- a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp @@ -66,6 +66,16 @@ void ChromaMatteOperation::executePixelSampled(float output[4], float x, float y /* Algorithm from book "Video Demistified," does not include the spill reduction part */ /* find theta, the angle that the color space should be rotated based on key */ + + /* rescale to -1.0..1.0 */ + // inImage[0] = (inImage[0] * 2.0f) - 1.0f; // UNUSED + inImage[1] = (inImage[1] * 2.0f) - 1.0f; + inImage[2] = (inImage[2] * 2.0f) - 1.0f; + + // inKey[0] = (inKey[0] * 2.0f) - 1.0f; // UNUSED + inKey[1] = (inKey[1] * 2.0f) - 1.0f; + inKey[2] = (inKey[2] * 2.0f) - 1.0f; + theta = atan2(inKey[2], inKey[1]); /*rotate the cb and cr into x/z space */ @@ -77,7 +87,7 @@ void ChromaMatteOperation::executePixelSampled(float output[4], float x, float y kfg = x_angle - (fabsf(z_angle) / tanf(acceptance / 2.f)); if (kfg > 0.f) { /* found a pixel that is within key color */ - alpha = (1.f - kfg) * (gain); + alpha = 1.0f - (kfg / gain); beta = atan2(z_angle, x_angle); diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp index 19209951005..54e0fb41abf 100644 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp @@ -23,6 +23,10 @@ #include "COM_ColorCorrectionOperation.h" #include "BLI_math.h" +extern "C" { +#include "IMB_colormanagement.h" +} + ColorCorrectionOperation::ColorCorrectionOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); @@ -90,7 +94,7 @@ void ColorCorrectionOperation::executePixelSampled(float output[4], float x, flo lift += (levelShadows * this->m_data->shadows.lift) + (levelMidtones * this->m_data->midtones.lift) + (levelHighlights * this->m_data->highlights.lift); float invgamma = 1.0f / gamma; - float luma = rgb_to_luma_y(inputImageColor); + float luma = IMB_colormanagement_get_luminance(inputImageColor); r = inputImageColor[0]; g = inputImageColor[1]; diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.cpp b/source/blender/compositor/operations/COM_ColorSpillOperation.cpp index 873ec72d9e9..0769e5d0b01 100644 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.cpp @@ -33,6 +33,7 @@ ColorSpillOperation::ColorSpillOperation() : NodeOperation() this->m_inputImageReader = NULL; this->m_inputFacReader = NULL; this->m_spillChannel = 1; // GREEN + this->m_spillMethod = 0; } void ColorSpillOperation::initExecution() @@ -91,7 +92,17 @@ void ColorSpillOperation::executePixelSampled(float output[4], float x, float y, this->m_inputFacReader->readSampled(fac, x, y, sampler); this->m_inputImageReader->readSampled(input, x, y, sampler); float rfac = min(1.0f, fac[0]); - float map = calculateMapValue(rfac, input); + float map; + + switch (this->m_spillMethod) { + case 0: /* simple */ + map = rfac * (input[this->m_spillChannel] - (this->m_settings->limscale * input[this->m_settings->limchan])); + break; + default: /* average */ + map = rfac * (input[this->m_spillChannel] - (this->m_settings->limscale * AVG(input[this->m_channel2], input[this->m_channel3]))); + break; + } + if (map > 0.0f) { output[0] = input[0] + this->m_rmut * (this->m_settings->uspillr * map); output[1] = input[1] + this->m_gmut * (this->m_settings->uspillg * map); @@ -102,13 +113,3 @@ void ColorSpillOperation::executePixelSampled(float output[4], float x, float y, copy_v4_v4(output, input); } } -float ColorSpillOperation::calculateMapValue(float fac, float *input) -{ - return fac * (input[this->m_spillChannel] - (this->m_settings->limscale * input[this->m_settings->limchan])); -} - - -float ColorSpillAverageOperation::calculateMapValue(float fac, float *input) -{ - return fac * (input[this->m_spillChannel] - (this->m_settings->limscale * AVG(input[this->m_channel2], input[this->m_channel3]))); -} diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.h b/source/blender/compositor/operations/COM_ColorSpillOperation.h index f9dc9ef7e25..3b94c293ec9 100644 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.h +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.h @@ -34,6 +34,7 @@ protected: SocketReader *m_inputImageReader; SocketReader *m_inputFacReader; int m_spillChannel; + int m_spillMethod; int m_channel2; int m_channel3; float m_rmut, m_gmut, m_bmut; @@ -53,12 +54,9 @@ public: void setSettings(NodeColorspill *nodeColorSpill) { this->m_settings = nodeColorSpill; } void setSpillChannel(int channel) { this->m_spillChannel = channel; } + void setSpillMethod(int method) { this->m_spillMethod = method; } float calculateMapValue(float fac, float *input); }; -class ColorSpillAverageOperation : public ColorSpillOperation { -public: - float calculateMapValue(float fac, float *input); -}; #endif diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index ef331a50dfd..76f74c144f6 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -52,6 +52,7 @@ CompositorOperation::CompositorOperation() : NodeOperation() this->m_active = false; this->m_sceneName[0] = '\0'; + this->m_viewName = NULL; } void CompositorOperation::initExecution() @@ -81,14 +82,16 @@ void CompositorOperation::deinitExecution() RenderResult *rr = RE_AcquireResultWrite(re); if (rr) { - if (rr->rectf != NULL) { - MEM_freeN(rr->rectf); + RenderView *rv = RE_RenderViewGetByName(rr, this->m_viewName); + + if (rv->rectf != NULL) { + MEM_freeN(rv->rectf); } - rr->rectf = this->m_outputBuffer; - if (rr->rectz != NULL) { - MEM_freeN(rr->rectz); + rv->rectf = this->m_outputBuffer; + if (rv->rectz != NULL) { + MEM_freeN(rv->rectz); } - rr->rectz = this->m_depthBuffer; + rv->rectz = this->m_depthBuffer; } else { if (this->m_outputBuffer) { @@ -125,7 +128,7 @@ void CompositorOperation::deinitExecution() } -void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber) +void CompositorOperation::executeRegion(rcti *rect, unsigned int /*tileNumber*/) { float color[8]; // 7 is enough float *buffer = this->m_outputBuffer; @@ -138,7 +141,7 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber) int y2 = rect->ymax; int offset = (y1 * this->getWidth() + x1); int add = (this->getWidth() - (x2 - x1)); - int offset4 = offset * COM_NUMBER_OF_CHANNELS; + int offset4 = offset * COM_NUM_CHANNELS_COLOR; int x; int y; bool breaked = false; @@ -196,14 +199,14 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber) this->m_depthInput->readSampled(color, input_x, input_y, COM_PS_NEAREST); zbuffer[offset] = color[0]; - offset4 += COM_NUMBER_OF_CHANNELS; + offset4 += COM_NUM_CHANNELS_COLOR; offset++; if (isBreaked()) { breaked = true; } } offset += add; - offset4 += add * COM_NUMBER_OF_CHANNELS; + offset4 += add * COM_NUM_CHANNELS_COLOR; } } diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h index 771c32ffd12..e81ba520695 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.h +++ b/source/blender/compositor/operations/COM_CompositorOperation.h @@ -75,13 +75,19 @@ private: * @brief operation is active for calculating final compo result */ bool m_active; + + /** + * @brief View name, used for multiview + */ + const char *m_viewName; public: CompositorOperation(); const bool isActiveCompositorOutput() const { return this->m_active; } void executeRegion(rcti *rect, unsigned int tileNumber); void setSceneName(const char *sceneName) { BLI_strncpy(this->m_sceneName, sceneName, sizeof(this->m_sceneName)); } + void setViewName(const char *viewName) { this->m_viewName = viewName; } void setRenderData(const RenderData *rd) { this->m_rd = rd; } - bool isOutputOperation(bool rendering) const { return this->isActiveCompositorOutput(); } + bool isOutputOperation(bool /*rendering*/) const { return this->isActiveCompositorOutput(); } void initExecution(); void deinitExecution(); const CompositorPriority getRenderPriority() const { return COM_PRIORITY_MEDIUM; } diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp index ea1443598a9..fa9a957f83c 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp @@ -60,7 +60,7 @@ void ConvertDepthToRadiusOperation::initExecution() this->m_inputOperation = this->getInputSocketReader(0); float focalDistance = determineFocalDistance(); - if (focalDistance == 0.0f) focalDistance = 1e10f; /* if the dof is 0.0 then set it be be far away */ + if (focalDistance == 0.0f) focalDistance = 1e10f; /* if the dof is 0.0 then set it to be far away */ this->m_inverseFocalDistance = 1.0f / focalDistance; this->m_aspect = (this->getWidth() > this->getHeight()) ? (this->getHeight() / (float)this->getWidth()) : (this->getWidth() / (float)this->getHeight()); this->m_aperture = 0.5f * (this->m_cam_lens / (this->m_aspect * cam_sensor)) / this->m_fStop; diff --git a/source/blender/compositor/operations/COM_ConvertOperation.cpp b/source/blender/compositor/operations/COM_ConvertOperation.cpp index 6b3e4067b18..8b8e8408208 100644 --- a/source/blender/compositor/operations/COM_ConvertOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertOperation.cpp @@ -22,6 +22,9 @@ #include "COM_ConvertOperation.h" +extern "C" { +#include "IMB_colormanagement.h" +} ConvertBaseOperation::ConvertBaseOperation() { @@ -49,9 +52,9 @@ ConvertValueToColorOperation::ConvertValueToColorOperation() : ConvertBaseOperat void ConvertValueToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - float inputValue[4]; - this->m_inputOperation->readSampled(inputValue, x, y, sampler); - output[0] = output[1] = output[2] = inputValue[0]; + float value; + this->m_inputOperation->readSampled(&value, x, y, sampler); + output[0] = output[1] = output[2] = value; output[3] = 1.0f; } @@ -84,7 +87,7 @@ void ConvertColorToBWOperation::executePixelSampled(float output[4], float x, fl { float inputColor[4]; this->m_inputOperation->readSampled(inputColor, x, y, sampler); - output[0] = rgb_to_bw(inputColor); + output[0] = IMB_colormanagement_get_luminance(inputColor); } @@ -98,8 +101,9 @@ ConvertColorToVectorOperation::ConvertColorToVectorOperation() : ConvertBaseOper void ConvertColorToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - this->m_inputOperation->readSampled(output, x, y, sampler); -} + float color[4]; + this->m_inputOperation->readSampled(color, x, y, sampler); + copy_v3_v3(output, color);} /* ******** Value to Vector ******** */ @@ -112,12 +116,9 @@ ConvertValueToVectorOperation::ConvertValueToVectorOperation() : ConvertBaseOper void ConvertValueToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - float input[4]; - this->m_inputOperation->readSampled(input, x, y, sampler); - output[0] = input[0]; - output[1] = input[0]; - output[2] = input[0]; - output[3] = 0.0f; + float value; + this->m_inputOperation->readSampled(&value, x, y, sampler); + output[0] = output[1] = output[2] = value; } @@ -292,6 +293,9 @@ void ConvertHSVToRGBOperation::executePixelSampled(float output[4], float x, flo float inputColor[4]; this->m_inputOperation->readSampled(inputColor, x, y, sampler); hsv_to_rgb_v(inputColor, output); + output[0] = max_ff(output[0], 0.0f); + output[1] = max_ff(output[1], 0.0f); + output[2] = max_ff(output[2], 0.0f); output[3] = inputColor[3]; } diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp index 657126d458c..e1ada9a8c39 100644 --- a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp @@ -28,7 +28,7 @@ ConvolutionEdgeFilterOperation::ConvolutionEdgeFilterOperation() : ConvolutionFi /* pass */ } -void ConvolutionEdgeFilterOperation::executePixel(float output[4], int x, int y, void *data) +void ConvolutionEdgeFilterOperation::executePixel(float output[4], int x, int y, void * /*data*/) { float in1[4], in2[4], res1[4] = {0.0}, res2[4] = {0.0}; diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp index 553a9827ffa..699db11d56e 100644 --- a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp @@ -69,7 +69,7 @@ void ConvolutionFilterOperation::deinitExecution() } -void ConvolutionFilterOperation::executePixel(float output[4], int x, int y, void *data) +void ConvolutionFilterOperation::executePixel(float output[4], int x, int y, void * /*data*/) { float in1[4]; float in2[4]; diff --git a/source/blender/compositor/operations/COM_CropOperation.cpp b/source/blender/compositor/operations/COM_CropOperation.cpp index c514b576dcf..e5427589fce 100644 --- a/source/blender/compositor/operations/COM_CropOperation.cpp +++ b/source/blender/compositor/operations/COM_CropOperation.cpp @@ -36,27 +36,28 @@ void CropBaseOperation::updateArea() SocketReader *inputReference = this->getInputSocketReader(0); float width = inputReference->getWidth(); float height = inputReference->getHeight(); + NodeTwoXYs local_settings = *this->m_settings; if (width > 0.0f && height > 0.0f) { if (this->m_relative) { - this->m_settings->x1 = width * this->m_settings->fac_x1; - this->m_settings->x2 = width * this->m_settings->fac_x2; - this->m_settings->y1 = height * this->m_settings->fac_y1; - this->m_settings->y2 = height * this->m_settings->fac_y2; + local_settings.x1 = width * local_settings.fac_x1; + local_settings.x2 = width * local_settings.fac_x2; + local_settings.y1 = height * local_settings.fac_y1; + local_settings.y2 = height * local_settings.fac_y2; } - if (width <= this->m_settings->x1 + 1) - this->m_settings->x1 = width - 1; - if (height <= this->m_settings->y1 + 1) - this->m_settings->y1 = height - 1; - if (width <= this->m_settings->x2 + 1) - this->m_settings->x2 = width - 1; - if (height <= this->m_settings->y2 + 1) - this->m_settings->y2 = height - 1; + if (width <= local_settings.x1 + 1) + local_settings.x1 = width - 1; + if (height <= local_settings.y1 + 1) + local_settings.y1 = height - 1; + if (width <= local_settings.x2 + 1) + local_settings.x2 = width - 1; + if (height <= local_settings.y2 + 1) + local_settings.y2 = height - 1; - this->m_xmax = max(this->m_settings->x1, this->m_settings->x2) + 1; - this->m_xmin = min(this->m_settings->x1, this->m_settings->x2); - this->m_ymax = max(this->m_settings->y1, this->m_settings->y2) + 1; - this->m_ymin = min(this->m_settings->y1, this->m_settings->y2); + this->m_xmax = max(local_settings.x1, local_settings.x2) + 1; + this->m_xmin = min(local_settings.x1, local_settings.x2); + this->m_ymax = max(local_settings.y1, local_settings.y2) + 1; + this->m_ymin = min(local_settings.y1, local_settings.y2); } else { this->m_xmax = 0; @@ -109,9 +110,9 @@ bool CropImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffe return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } -void CropImageOperation::determineResolution(unsigned int resolution[2], unsigned int preferedResolution[2]) +void CropImageOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) { - NodeOperation::determineResolution(resolution, preferedResolution); + NodeOperation::determineResolution(resolution, preferredResolution); updateArea(); resolution[0] = this->m_xmax - this->m_xmin; resolution[1] = this->m_ymax - this->m_ymin; diff --git a/source/blender/compositor/operations/COM_CropOperation.h b/source/blender/compositor/operations/COM_CropOperation.h index 4890ede18a9..0b396ca7800 100644 --- a/source/blender/compositor/operations/COM_CropOperation.h +++ b/source/blender/compositor/operations/COM_CropOperation.h @@ -56,7 +56,7 @@ private: public: CropImageOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void determineResolution(unsigned int resolution[2], unsigned int preferedResolution[2]); + void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.cpp b/source/blender/compositor/operations/COM_DespeckleOperation.cpp index 186c17845f3..1a827aae67e 100644 --- a/source/blender/compositor/operations/COM_DespeckleOperation.cpp +++ b/source/blender/compositor/operations/COM_DespeckleOperation.cpp @@ -52,7 +52,7 @@ BLI_INLINE int color_diff(const float a[3], const float b[3], const float thresh (fabsf(a[2] - b[2]) > threshold)); } -void DespeckleOperation::executePixel(float output[4], int x, int y, void *data) +void DespeckleOperation::executePixel(float output[4], int x, int y, void * /*data*/) { float w = 0.0f; float color_org[4]; diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp index cbf4ce693d9..fc3ec7dd11a 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp @@ -56,7 +56,7 @@ void DilateErodeThresholdOperation::initExecution() } } -void *DilateErodeThresholdOperation::initializeTileData(rcti *rect) +void *DilateErodeThresholdOperation::initializeTileData(rcti * /*rect*/) { void *buffer = this->m_inputProgram->initializeTileData(NULL); return buffer; @@ -82,18 +82,18 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y, const int bufferWidth = BLI_rcti_size_x(rect); int offset; - this->m_inputProgram->read(inputValue, x, y, NULL); + inputBuffer->read(inputValue, x, y); if (inputValue[0] > sw) { for (int yi = miny; yi < maxy; yi++) { const float dy = yi - y; - offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; + offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)); for (int xi = minx; xi < maxx; xi++) { if (buffer[offset] < sw) { const float dx = xi - x; const float dis = dx * dx + dy * dy; mindist = min(mindist, dis); } - offset += 4; + offset ++; } } pixelvalue = -sqrtf(mindist); @@ -101,15 +101,14 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y, else { for (int yi = miny; yi < maxy; yi++) { const float dy = yi - y; - offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; + offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)); for (int xi = minx; xi < maxx; xi++) { if (buffer[offset] > sw) { const float dx = xi - x; const float dis = dx * dx + dy * dy; mindist = min(mindist, dis); } - offset += 4; - + offset ++; } } pixelvalue = sqrtf(mindist); @@ -181,7 +180,7 @@ void DilateDistanceOperation::initExecution() } } -void *DilateDistanceOperation::initializeTileData(rcti *rect) +void *DilateDistanceOperation::initializeTileData(rcti * /*rect*/) { void *buffer = this->m_inputProgram->initializeTileData(NULL); return buffer; @@ -206,14 +205,14 @@ void DilateDistanceOperation::executePixel(float output[4], int x, int y, void * for (int yi = miny; yi < maxy; yi++) { const float dy = yi - y; - offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; + offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)); for (int xi = minx; xi < maxx; xi++) { const float dx = xi - x; const float dis = dx * dx + dy * dy; if (dis <= mindist) { value = max(buffer[offset], value); } - offset += 4; + offset ++; } } output[0] = value; @@ -239,7 +238,7 @@ bool DilateDistanceOperation::determineDependingAreaOfInterest(rcti *input, Read void DilateDistanceOperation::executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, - list<cl_kernel> *clKernelsToCleanUp) + list<cl_kernel> * /*clKernelsToCleanUp*/) { cl_kernel dilateKernel = device->COM_clCreateKernel("dilateKernel", NULL); @@ -280,14 +279,14 @@ void ErodeDistanceOperation::executePixel(float output[4], int x, int y, void *d for (int yi = miny; yi < maxy; yi++) { const float dy = yi - y; - offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; + offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)); for (int xi = minx; xi < maxx; xi++) { const float dx = xi - x; const float dis = dx * dx + dy * dy; if (dis <= mindist) { value = min(buffer[offset], value); } - offset += 4; + offset ++; } } output[0] = value; @@ -296,7 +295,7 @@ void ErodeDistanceOperation::executePixel(float output[4], int x, int y, void *d void ErodeDistanceOperation::executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, - list<cl_kernel> *clKernelsToCleanUp) + list<cl_kernel> * /*clKernelsToCleanUp*/) { cl_kernel erodeKernel = device->COM_clCreateKernel("erodeKernel", NULL); @@ -383,7 +382,7 @@ void *DilateStepOperation::initializeTileData(rcti *rect) buf[x] = -FLT_MAX; } for (x = xmin; x < xmax; ++x) { - buf[x - rect->xmin + window - 1] = buffer[4 * (y * width + x)]; + buf[x - rect->xmin + window - 1] = buffer[(y * width + x)]; } for (i = 0; i < (bwidth + 3 * half_window) / window; i++) { @@ -447,7 +446,7 @@ void DilateStepOperation::deinitExecution() this->m_inputProgram = NULL; } -void DilateStepOperation::deinitializeTileData(rcti *rect, void *data) +void DilateStepOperation::deinitializeTileData(rcti * /*rect*/, void *data) { tile_info *tile = (tile_info *)data; MEM_freeN(tile->buffer); @@ -510,7 +509,7 @@ void *ErodeStepOperation::initializeTileData(rcti *rect) buf[x] = FLT_MAX; } for (x = xmin; x < xmax; ++x) { - buf[x - rect->xmin + window - 1] = buffer[4 * (y * width + x)]; + buf[x - rect->xmin + window - 1] = buffer[(y * width + x)]; } for (i = 0; i < (bwidth + 3 * half_window) / window; i++) { diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp index 67f52934b13..14881ebb265 100644 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp @@ -60,25 +60,25 @@ void DirectionalBlurOperation::initExecution() this->m_center_y_pix = center_y * height; this->m_tx = itsc * D * cosf(a); - this->m_ty = -itsc *D *sinf(a); + this->m_ty = -itsc * D * sinf(a); this->m_sc = itsc * zoom; this->m_rot = itsc * spin; } -void DirectionalBlurOperation::executePixel(float output[4], int x, int y, void *data) +void DirectionalBlurOperation::executePixel(float output[4], int x, int y, void * /*data*/) { const int iterations = pow(2.0f, this->m_data->iter); - float col[4] = {0, 0, 0, 0}; - float col2[4] = {0, 0, 0, 0}; - this->m_inputProgram->readSampled(col2, x, y, COM_PS_NEAREST); + float col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + float col2[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + this->m_inputProgram->readSampled(col2, x, y, COM_PS_BILINEAR); float ltx = this->m_tx; float lty = this->m_ty; float lsc = this->m_sc; float lrot = this->m_rot; /* blur the image */ for (int i = 0; i < iterations; ++i) { - const float cs = cos(lrot), ss = sin(lrot); + const float cs = cosf(lrot), ss = sinf(lrot); const float isc = 1.0f / (1.0f + lsc); const float v = isc * (y - this->m_center_y_pix) + lty; @@ -87,7 +87,7 @@ void DirectionalBlurOperation::executePixel(float output[4], int x, int y, void this->m_inputProgram->readSampled(col, cs * u + ss * v + this->m_center_x_pix, cs * v - ss * u + this->m_center_y_pix, - COM_PS_NEAREST); + COM_PS_BILINEAR); add_v4_v4(col2, col); @@ -104,7 +104,7 @@ void DirectionalBlurOperation::executePixel(float output[4], int x, int y, void void DirectionalBlurOperation::executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, - list<cl_kernel> *clKernelsToCleanUp) + list<cl_kernel> * /*clKernelsToCleanUp*/) { cl_kernel directionalBlurKernel = device->COM_clCreateKernel("directionalBlurKernel", NULL); @@ -132,7 +132,7 @@ void DirectionalBlurOperation::deinitExecution() this->m_inputProgram = NULL; } -bool DirectionalBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool DirectionalBlurOperation::determineDependingAreaOfInterest(rcti * /*input*/, ReadBufferOperation *readOperation, rcti *output) { rcti newInput; diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cpp b/source/blender/compositor/operations/COM_DisplaceOperation.cpp index 7dacc3239c5..9b3377e887a 100644 --- a/source/blender/compositor/operations/COM_DisplaceOperation.cpp +++ b/source/blender/compositor/operations/COM_DisplaceOperation.cpp @@ -49,15 +49,19 @@ void DisplaceOperation::initExecution() this->m_height_x4 = this->getHeight() * 4; } -void DisplaceOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void DisplaceOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { float xy[2] = { x, y }; float uv[2], deriv[2][2]; pixelTransform(xy, uv, deriv); - - /* EWA filtering (without nearest it gets blurry with NO distortion) */ - this->m_inputColorProgram->readFiltered(output, uv[0], uv[1], deriv[0], deriv[1], COM_PS_BILINEAR); + if (is_zero_v2(deriv[0]) && is_zero_v2(deriv[1])) { + this->m_inputColorProgram->readSampled(output, uv[0], uv[1], COM_PS_BILINEAR); + } + else { + /* EWA filtering (without nearest it gets blurry with NO distortion) */ + this->m_inputColorProgram->readFiltered(output, uv[0], uv[1], deriv[0], deriv[1]); + } } bool DisplaceOperation::read_displacement(float x, float y, float xscale, float yscale, const float origin[2], float &r_u, float &r_v) diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp index 5006720f091..76afedf4b2a 100644 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp @@ -1237,7 +1237,7 @@ DoubleEdgeMaskOperation::DoubleEdgeMaskOperation() : NodeOperation() this->setComplex(true); } -bool DoubleEdgeMaskOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool DoubleEdgeMaskOperation::determineDependingAreaOfInterest(rcti * /*input*/, ReadBufferOperation *readOperation, rcti *output) { if (this->m_cachedInstance == NULL) { rcti newInput; @@ -1270,11 +1270,9 @@ void *DoubleEdgeMaskOperation::initializeTileData(rcti *rect) MemoryBuffer *innerMask = (MemoryBuffer *)this->m_inputInnerMask->initializeTileData(rect); MemoryBuffer *outerMask = (MemoryBuffer *)this->m_inputOuterMask->initializeTileData(rect); float *data = (float *)MEM_mallocN(sizeof(float) * this->getWidth() * this->getHeight(), __func__); - float *imask = innerMask->convertToValueBuffer(); - float *omask = outerMask->convertToValueBuffer(); + float *imask = innerMask->getBuffer(); + float *omask = outerMask->getBuffer(); doDoubleEdgeMask(imask, omask, data); - MEM_freeN(imask); - MEM_freeN(omask); this->m_cachedInstance = data; } unlockMutex(); diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp index 705a8c07381..968319b3f46 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -37,7 +37,7 @@ void FastGaussianBlurOperation::executePixel(float output[4], int x, int y, void newData->read(output, x, y); } -bool FastGaussianBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool FastGaussianBlurOperation::determineDependingAreaOfInterest(rcti * /*input*/, ReadBufferOperation *readOperation, rcti *output) { rcti newInput; rcti sizeInput; @@ -92,16 +92,16 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect) this->m_sy = this->m_data.sizey * this->m_size / 2.0f; if ((this->m_sx == this->m_sy) && (this->m_sx > 0.f)) { - for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) + for (c = 0; c < COM_NUM_CHANNELS_COLOR; ++c) IIR_gauss(copy, this->m_sx, c, 3); } else { if (this->m_sx > 0.0f) { - for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) + for (c = 0; c < COM_NUM_CHANNELS_COLOR; ++c) IIR_gauss(copy, this->m_sx, c, 1); } if (this->m_sy > 0.0f) { - for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) + for (c = 0; c < COM_NUM_CHANNELS_COLOR; ++c) IIR_gauss(copy, this->m_sy, c, 2); } } @@ -120,6 +120,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign unsigned int x, y, sz; unsigned int i; float *buffer = src->getBuffer(); + const unsigned int num_channels = src->get_num_channels(); // <0.5 not valid, though can have a possibly useful sort of sharpening effect if (sigma < 0.5f) return; @@ -198,31 +199,31 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign int offset; for (y = 0; y < src_height; ++y) { const int yx = y * src_width; - offset = yx * COM_NUMBER_OF_CHANNELS + chan; + offset = yx * num_channels + chan; for (x = 0; x < src_width; ++x) { X[x] = buffer[offset]; - offset += COM_NUMBER_OF_CHANNELS; + offset += num_channels; } YVV(src_width); - offset = yx * COM_NUMBER_OF_CHANNELS + chan; + offset = yx * num_channels + chan; for (x = 0; x < src_width; ++x) { buffer[offset] = Y[x]; - offset += COM_NUMBER_OF_CHANNELS; + offset += num_channels; } } } if (xy & 2) { // V int offset; - const int add = src_width * COM_NUMBER_OF_CHANNELS; + const int add = src_width * num_channels; for (x = 0; x < src_width; ++x) { - offset = x * COM_NUMBER_OF_CHANNELS + chan; + offset = x * num_channels + chan; for (y = 0; y < src_height; ++y) { X[y] = buffer[offset]; offset += add; } YVV(src_height); - offset = x * COM_NUMBER_OF_CHANNELS + chan; + offset = x * num_channels + chan; for (y = 0; y < src_height; ++y) { buffer[offset] = Y[y]; offset += add; @@ -256,7 +257,7 @@ void FastGaussianBlurValueOperation::executePixel(float output[4], int x, int y, newData->read(output, x, y); } -bool FastGaussianBlurValueOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool FastGaussianBlurValueOperation::determineDependingAreaOfInterest(rcti * /*input*/, ReadBufferOperation *readOperation, rcti *output) { rcti newInput; @@ -298,7 +299,7 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect) if (this->m_overlay == FAST_GAUSS_OVERLAY_MIN) { float *src = newBuf->getBuffer(); float *dst = copy->getBuffer(); - for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUMBER_OF_CHANNELS, dst += COM_NUMBER_OF_CHANNELS) { + for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUM_CHANNELS_VALUE, dst += COM_NUM_CHANNELS_VALUE) { if (*src < *dst) { *dst = *src; } @@ -307,7 +308,7 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect) else if (this->m_overlay == FAST_GAUSS_OVERLAY_MAX) { float *src = newBuf->getBuffer(); float *dst = copy->getBuffer(); - for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUMBER_OF_CHANNELS, dst += COM_NUMBER_OF_CHANNELS) { + for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUM_CHANNELS_VALUE, dst += COM_NUM_CHANNELS_VALUE) { if (*src > *dst) { *dst = *src; } diff --git a/source/blender/compositor/operations/COM_FlipOperation.cpp b/source/blender/compositor/operations/COM_FlipOperation.cpp index 3de2ae9dabc..7ff7d694fa8 100644 --- a/source/blender/compositor/operations/COM_FlipOperation.cpp +++ b/source/blender/compositor/operations/COM_FlipOperation.cpp @@ -44,8 +44,8 @@ void FlipOperation::deinitExecution() void FlipOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - float nx = this->m_flipX ? this->getWidth() - 1 - x : x; - float ny = this->m_flipY ? this->getHeight() - 1 - y : y; + float nx = this->m_flipX ? ((int)this->getWidth() - 1) - x : x; + float ny = this->m_flipY ? ((int)this->getHeight() - 1) - y : y; this->m_inputOperation->readSampled(output, nx, ny, sampler); } @@ -55,16 +55,18 @@ bool FlipOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOper rcti newInput; if (this->m_flipX) { - newInput.xmax = (this->getWidth() - 1 - input->xmin) + 1; - newInput.xmin = (this->getWidth() - 1 - input->xmax) - 1; + const int w = (int)this->getWidth() - 1; + newInput.xmax = (w - input->xmin) + 1; + newInput.xmin = (w - input->xmax) - 1; } else { newInput.xmin = input->xmin; newInput.xmax = input->xmax; } if (this->m_flipY) { - newInput.ymax = (this->getHeight() - 1 - input->ymin) + 1; - newInput.ymin = (this->getHeight() - 1 - input->ymax) - 1; + const int h = (int)this->getHeight() - 1; + newInput.ymax = (h - input->ymin) + 1; + newInput.ymin = (h - input->ymax) - 1; } else { newInput.ymin = input->ymin; diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp index c78347e7b1c..cbe41076b2a 100644 --- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp @@ -36,7 +36,7 @@ GaussianAlphaXBlurOperation::GaussianAlphaXBlurOperation() : BlurBaseOperation(C this->m_falloff = -1; /* intentionally invalid, so we can detect uninitialized values */ } -void *GaussianAlphaXBlurOperation::initializeTileData(rcti *rect) +void *GaussianAlphaXBlurOperation::initializeTileData(rcti * /*rect*/) { lockMutex(); if (!this->m_sizeavailable) { @@ -102,15 +102,14 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo /* *** this is the main part which is different to 'GaussianXBlurOperation' *** */ int step = getStep(); - int offsetadd = getOffsetAdd(); - int bufferindex = ((xmin - bufferstartx) * 4) + ((ymin - bufferstarty) * 4 * bufferwidth); + int bufferindex = ((xmin - bufferstartx)) + ((ymin - bufferstarty) * bufferwidth); /* gauss */ float alpha_accum = 0.0f; float multiplier_accum = 0.0f; /* dilate */ - float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */ + float value_max = finv_test(buffer[(x) + (y * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */ float distfacinv_max = 1.0f; /* 0 to 1 */ for (int nx = xmin; nx < xmax; nx += step) { @@ -134,7 +133,7 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo distfacinv_max = multiplier; } } - bufferindex += offsetadd; + bufferindex += step; } /* blend between the max value and gauss blue - gives nice feather */ diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp index ab97c8b0d13..30563e8cc45 100644 --- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp @@ -36,7 +36,7 @@ GaussianAlphaYBlurOperation::GaussianAlphaYBlurOperation() : BlurBaseOperation(C this->m_falloff = -1; /* intentionally invalid, so we can detect uninitialized values */ } -void *GaussianAlphaYBlurOperation::initializeTileData(rcti *rect) +void *GaussianAlphaYBlurOperation::initializeTileData(rcti * /*rect*/) { lockMutex(); if (!this->m_sizeavailable) { @@ -108,11 +108,11 @@ void GaussianAlphaYBlurOperation::executePixel(float output[4], int x, int y, vo float multiplier_accum = 0.0f; /* dilate */ - float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */ + float value_max = finv_test(buffer[(x) + (y * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */ float distfacinv_max = 1.0f; /* 0 to 1 */ for (int ny = ymin; ny < ymax; ny += step) { - int bufferindex = ((xmin - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth); + int bufferindex = ((xmin - bufferstartx)) + ((ny - bufferstarty) * bufferwidth); const int index = (ny - y) + this->m_filtersize; float value = finv_test(buffer[bufferindex], do_invert); diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index 441b623b589..37d59229e50 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -32,7 +32,7 @@ GaussianBokehBlurOperation::GaussianBokehBlurOperation() : BlurBaseOperation(COM this->m_gausstab = NULL; } -void *GaussianBokehBlurOperation::initializeTileData(rcti *rect) +void *GaussianBokehBlurOperation::initializeTileData(rcti * /*rect*/) { lockMutex(); if (!this->m_sizeavailable) { @@ -205,7 +205,7 @@ GaussianBlurReferenceOperation::GaussianBlurReferenceOperation() : BlurBaseOpera this->m_maintabs = NULL; } -void *GaussianBlurReferenceOperation::initializeTileData(rcti *rect) +void *GaussianBlurReferenceOperation::initializeTileData(rcti * /*rect*/) { void *buffer = getInputOperation(0)->initializeTileData(NULL); return buffer; @@ -296,7 +296,7 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y, int minyr = y - refrady < 0 ? -y : -refrady; int maxyr = y + refrady > imgy ? imgy - y : refrady; - float *srcd = buffer + COM_NUMBER_OF_CHANNELS * ( (y + minyr) * imgx + x + minxr); + float *srcd = buffer + COM_NUM_CHANNELS_COLOR * ( (y + minyr) * imgx + x + minxr); gausstabx = m_maintabs[refradx - 1]; gausstabcentx = gausstabx + refradx; @@ -304,9 +304,9 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y, gausstabcenty = gausstaby + refrady; sum = gval = rval = bval = aval = 0.0f; - for (i = minyr; i < maxyr; i++, srcd += COM_NUMBER_OF_CHANNELS * imgx) { + for (i = minyr; i < maxyr; i++, srcd += COM_NUM_CHANNELS_COLOR * imgx) { src = srcd; - for (j = minxr; j < maxxr; j++, src += COM_NUMBER_OF_CHANNELS) { + for (j = minxr; j < maxxr; j++, src += COM_NUM_CHANNELS_COLOR) { val = gausstabcenty[i] * gausstabcentx[j]; sum += val; diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp index 0aefba3bb7c..29ed4334412 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp @@ -21,6 +21,7 @@ */ #include "COM_GaussianXBlurOperation.h" +#include "COM_OpenCLDevice.h" #include "BLI_math.h" #include "MEM_guardedalloc.h" @@ -37,7 +38,7 @@ GaussianXBlurOperation::GaussianXBlurOperation() : BlurBaseOperation(COM_DT_COLO this->m_filtersize = 0; } -void *GaussianXBlurOperation::initializeTileData(rcti *rect) +void *GaussianXBlurOperation::initializeTileData(rcti * /*rect*/) { lockMutex(); if (!this->m_sizeavailable) { @@ -62,7 +63,6 @@ void GaussianXBlurOperation::initExecution() this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize); #ifdef __SSE2__ this->m_gausstab_sse = BlurBaseOperation::convert_gausstab_sse(this->m_gausstab, - rad, m_filtersize); #endif } @@ -78,7 +78,6 @@ void GaussianXBlurOperation::updateGauss() this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize); #ifdef __SSE2__ this->m_gausstab_sse = BlurBaseOperation::convert_gausstab_sse(this->m_gausstab, - rad, m_filtersize); #endif } @@ -124,6 +123,32 @@ void GaussianXBlurOperation::executePixel(float output[4], int x, int y, void *d mul_v4_v4fl(output, color_accum, 1.0f / multiplier_accum); } +void GaussianXBlurOperation::executeOpenCL(OpenCLDevice *device, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, + list<cl_kernel> * /*clKernelsToCleanUp*/) +{ + cl_kernel gaussianXBlurOperationKernel = device->COM_clCreateKernel("gaussianXBlurOperationKernel", NULL); + cl_int filter_size = this->m_filtersize; + + cl_mem gausstab = clCreateBuffer(device->getContext(), + CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, + sizeof(float) * (this->m_filtersize * 2 + 1), + this->m_gausstab, + NULL); + + device->COM_clAttachMemoryBufferToKernelParameter(gaussianXBlurOperationKernel, 0, 1, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram); + device->COM_clAttachOutputMemoryBufferToKernelParameter(gaussianXBlurOperationKernel, 2, clOutputBuffer); + device->COM_clAttachMemoryBufferOffsetToKernelParameter(gaussianXBlurOperationKernel, 3, outputMemoryBuffer); + clSetKernelArg(gaussianXBlurOperationKernel, 4, sizeof(cl_int), &filter_size); + device->COM_clAttachSizeToKernelParameter(gaussianXBlurOperationKernel, 5, this); + clSetKernelArg(gaussianXBlurOperationKernel, 6, sizeof(cl_mem), &gausstab); + + device->COM_clEnqueueRange(gaussianXBlurOperationKernel, outputMemoryBuffer, 7, this); + + clReleaseMemObject(gausstab); +} + void GaussianXBlurOperation::deinitExecution() { BlurBaseOperation::deinitExecution(); diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h index e391320a007..d7ae8b1e3dc 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h @@ -40,7 +40,12 @@ public: * @brief the inner loop of this program */ void executePixel(float output[4], int x, int y, void *data); - + + void executeOpenCL(OpenCLDevice *device, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, + list<cl_kernel> *clKernelsToCleanUp); + /** * @brief initialize the execution */ @@ -53,5 +58,9 @@ public: void *initializeTileData(rcti *rect); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void checkOpenCL() { + this->setOpenCL(m_data.sizex >= 128); + } }; #endif diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp index a05a1ab6a23..4b55333c08c 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp @@ -21,6 +21,7 @@ */ #include "COM_GaussianYBlurOperation.h" +#include "COM_OpenCLDevice.h" #include "BLI_math.h" #include "MEM_guardedalloc.h" @@ -37,7 +38,7 @@ GaussianYBlurOperation::GaussianYBlurOperation() : BlurBaseOperation(COM_DT_COLO this->m_filtersize = 0; } -void *GaussianYBlurOperation::initializeTileData(rcti *rect) +void *GaussianYBlurOperation::initializeTileData(rcti * /*rect*/) { lockMutex(); if (!this->m_sizeavailable) { @@ -61,7 +62,6 @@ void GaussianYBlurOperation::initExecution() this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize); #ifdef __SSE2__ this->m_gausstab_sse = BlurBaseOperation::convert_gausstab_sse(this->m_gausstab, - rad, m_filtersize); #endif } @@ -77,7 +77,6 @@ void GaussianYBlurOperation::updateGauss() this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize); #ifdef __SSE2__ this->m_gausstab_sse = BlurBaseOperation::convert_gausstab_sse(this->m_gausstab, - rad, m_filtersize); #endif } @@ -126,6 +125,32 @@ void GaussianYBlurOperation::executePixel(float output[4], int x, int y, void *d mul_v4_v4fl(output, color_accum, 1.0f / multiplier_accum); } +void GaussianYBlurOperation::executeOpenCL(OpenCLDevice *device, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, + list<cl_kernel> * /*clKernelsToCleanUp*/) +{ + cl_kernel gaussianYBlurOperationKernel = device->COM_clCreateKernel("gaussianYBlurOperationKernel", NULL); + cl_int filter_size = this->m_filtersize; + + cl_mem gausstab = clCreateBuffer(device->getContext(), + CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, + sizeof(float) * (this->m_filtersize * 2 + 1), + this->m_gausstab, + NULL); + + device->COM_clAttachMemoryBufferToKernelParameter(gaussianYBlurOperationKernel, 0, 1, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram); + device->COM_clAttachOutputMemoryBufferToKernelParameter(gaussianYBlurOperationKernel, 2, clOutputBuffer); + device->COM_clAttachMemoryBufferOffsetToKernelParameter(gaussianYBlurOperationKernel, 3, outputMemoryBuffer); + clSetKernelArg(gaussianYBlurOperationKernel, 4, sizeof(cl_int), &filter_size); + device->COM_clAttachSizeToKernelParameter(gaussianYBlurOperationKernel, 5, this); + clSetKernelArg(gaussianYBlurOperationKernel, 6, sizeof(cl_mem), &gausstab); + + device->COM_clEnqueueRange(gaussianYBlurOperationKernel, outputMemoryBuffer, 7, this); + + clReleaseMemObject(gausstab); +} + void GaussianYBlurOperation::deinitExecution() { BlurBaseOperation::deinitExecution(); diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h index 22b6562077d..4b5751c0968 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h @@ -40,7 +40,12 @@ public: * the inner loop of this program */ void executePixel(float output[4], int x, int y, void *data); - + + void executeOpenCL(OpenCLDevice *device, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, + list<cl_kernel> *clKernelsToCleanUp); + /** * @brief initialize the execution */ @@ -53,5 +58,9 @@ public: void *initializeTileData(rcti *rect); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void checkOpenCL() { + this->setOpenCL(m_data.sizex >= 128); + } }; #endif diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp index 99c745d7fb0..1acbd2ae090 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp @@ -49,13 +49,13 @@ MemoryBuffer *GlareBaseOperation::createMemoryBuffer(rcti *rect2) rect.ymin = 0; rect.xmax = getWidth(); rect.ymax = getHeight(); - MemoryBuffer *result = new MemoryBuffer(NULL, &rect); + MemoryBuffer *result = new MemoryBuffer(COM_DT_COLOR, &rect); float *data = result->getBuffer(); this->generateGlare(data, tile, this->m_settings); return result; } -bool GlareBaseOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool GlareBaseOperation::determineDependingAreaOfInterest(rcti * /*input*/, ReadBufferOperation *readOperation, rcti *output) { if (isCached()) { return false; diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp index 99a7c5b64c4..04993b08ddf 100644 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp @@ -259,8 +259,8 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2) float *kernelBuffer = in2->getBuffer(); float *imageBuffer = in1->getBuffer(); - MemoryBuffer *rdst = new MemoryBuffer(NULL, in1->getRect()); - memset(rdst->getBuffer(), 0, rdst->getWidth() * rdst->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); + MemoryBuffer *rdst = new MemoryBuffer(COM_DT_COLOR, in1->getRect()); + memset(rdst->getBuffer(), 0, rdst->getWidth() * rdst->getHeight() * COM_NUM_CHANNELS_COLOR * sizeof(float)); // convolution result width & height w2 = 2 * kernelWidth - 1; @@ -276,7 +276,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2) // normalize convolutor wt[0] = wt[1] = wt[2] = 0.f; for (y = 0; y < kernelHeight; y++) { - colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS]; + colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUM_CHANNELS_COLOR]; for (x = 0; x < kernelWidth; x++) add_v3_v3(wt, colp[x]); } @@ -284,7 +284,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2) if (wt[1] != 0.f) wt[1] = 1.f / wt[1]; if (wt[2] != 0.f) wt[2] = 1.f / wt[2]; for (y = 0; y < kernelHeight; y++) { - colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS]; + colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUM_CHANNELS_COLOR]; for (x = 0; x < kernelWidth; x++) mul_v3_v3(colp[x], wt); } @@ -313,7 +313,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2) // in2, channel ch -> data1 for (y = 0; y < kernelHeight; y++) { fp = &data1ch[y * w2]; - colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS]; + colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUM_CHANNELS_COLOR]; for (x = 0; x < kernelWidth; x++) fp[x] = colp[x][ch]; } @@ -325,7 +325,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2) int yy = ybl * ybsz + y; if (yy >= imageHeight) continue; fp = &data2[y * w2]; - colp = (fRGB *)&imageBuffer[yy * imageWidth * COM_NUMBER_OF_CHANNELS]; + colp = (fRGB *)&imageBuffer[yy * imageWidth * COM_NUM_CHANNELS_COLOR]; for (x = 0; x < xbsz; x++) { int xx = xbl * xbsz + x; if (xx >= imageWidth) continue; @@ -349,7 +349,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2) const int yy = ybl * ybsz + y - hh; if ((yy < 0) || (yy >= imageHeight)) continue; fp = &data2[y * w2]; - colp = (fRGB *)&rdst->getBuffer()[yy * imageWidth * COM_NUMBER_OF_CHANNELS]; + colp = (fRGB *)&rdst->getBuffer()[yy * imageWidth * COM_NUM_CHANNELS_COLOR]; for (x = 0; x < (int)w2; x++) { const int xx = xbl * xbsz + x - hw; if ((xx < 0) || (xx >= imageWidth)) continue; @@ -364,7 +364,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2) MEM_freeN(data2); MEM_freeN(data1); - memcpy(dst, rdst->getBuffer(), sizeof(float) * imageWidth * imageHeight * COM_NUMBER_OF_CHANNELS); + memcpy(dst, rdst->getBuffer(), sizeof(float) * imageWidth * imageHeight * COM_NUM_CHANNELS_COLOR); delete(rdst); } @@ -381,7 +381,7 @@ void GlareFogGlowOperation::generateGlare(float *data, MemoryBuffer *inputTile, // make the convolution kernel rcti kernelRect; BLI_rcti_init(&kernelRect, 0, sz, 0, sz); - ckrn = new MemoryBuffer(NULL, &kernelRect); + ckrn = new MemoryBuffer(COM_DT_COLOR, &kernelRect); scale = 0.25f * sqrtf((float)(sz * sz)); diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp index 8854be52ded..eea6588a9a6 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp @@ -65,7 +65,7 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No if (isBreaked()) breaked = true; if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 2, 3); - if (settings->iter & 1) ofs = 0.5f; else ofs = 0.f; + ofs = (settings->iter & 1) ? 0.5f : 0.0f; for (x = 0; x < (settings->iter * 4); x++) { y = x & 3; cm[x][0] = cm[x][1] = cm[x][2] = 1; @@ -97,7 +97,7 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No } - memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); + memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUM_CHANNELS_COLOR * sizeof(float)); for (n = 1; n < settings->iter && (!breaked); n++) { for (y = 0; y < gbuf->getHeight() && (!breaked); y++) { v = ((float)y + 0.5f) / (float)gbuf->getHeight(); @@ -117,9 +117,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No } if (isBreaked()) breaked = true; } - memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); + memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth() * tbuf1->getHeight() * COM_NUM_CHANNELS_COLOR * sizeof(float)); } - memcpy(data, gbuf->getBuffer(), gbuf->getWidth() * gbuf->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); + memcpy(data, gbuf->getBuffer(), gbuf->getWidth() * gbuf->getHeight() * COM_NUM_CHANNELS_COLOR * sizeof(float)); delete gbuf; delete tbuf1; diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp index 5644ff30ef3..deeb5094bd0 100644 --- a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp @@ -36,7 +36,7 @@ void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile, bool breaked = false; MemoryBuffer *tsrc = inputTile->duplicate(); - MemoryBuffer *tdst = new MemoryBuffer(NULL, inputTile->getRect()); + MemoryBuffer *tdst = new MemoryBuffer(COM_DT_COLOR, inputTile->getRect()); tdst->clear(); memset(data, 0, size4 * sizeof(float)); diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp index 78e1e80cafc..d2bd7cbeeab 100644 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp @@ -23,6 +23,10 @@ #include "COM_GlareThresholdOperation.h" #include "BLI_math.h" +extern "C" { +#include "IMB_colormanagement.h" +} + GlareThresholdOperation::GlareThresholdOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR, COM_SC_FIT); @@ -47,7 +51,7 @@ void GlareThresholdOperation::executePixelSampled(float output[4], float x, floa const float threshold = this->m_settings->threshold; this->m_inputProgram->readSampled(output, x, y, sampler); - if (rgb_to_luma_y(output) >= threshold) { + if (IMB_colormanagement_get_luminance(output) >= threshold) { output[0] -= threshold, output[1] -= threshold, output[2] -= threshold; output[0] = max(output[0], 0.0f); output[1] = max(output[1], 0.0f); diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp index 2733c483146..c55366ab370 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cpp +++ b/source/blender/compositor/operations/COM_ImageOperation.cpp @@ -25,6 +25,7 @@ #include "BLI_listbase.h" #include "DNA_image_types.h" #include "BKE_image.h" +#include "BKE_scene.h" #include "BLI_math.h" extern "C" { @@ -48,6 +49,8 @@ BaseImageOperation::BaseImageOperation() : NodeOperation() this->m_framenumber = 0; this->m_depthBuffer = NULL; this->m_numberOfChannels = 0; + this->m_rd = NULL; + this->m_viewName = NULL; } ImageOperation::ImageOperation() : BaseImageOperation() { @@ -65,8 +68,16 @@ ImageDepthOperation::ImageDepthOperation() : BaseImageOperation() ImBuf *BaseImageOperation::getImBuf() { ImBuf *ibuf; - - ibuf = BKE_image_acquire_ibuf(this->m_image, this->m_imageUser, NULL); + ImageUser iuser = *this->m_imageUser; + + if (this->m_image == NULL) + return NULL; + + /* local changes to the original ImageUser */ + if (BKE_image_is_multilayer(this->m_image) == false) + iuser.multi_index = BKE_scene_multiview_view_id_get(this->m_rd, this->m_viewName); + + ibuf = BKE_image_acquire_ibuf(this->m_image, &iuser, NULL); if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL)) { BKE_image_release_ibuf(this->m_image, ibuf, NULL); return NULL; @@ -96,7 +107,7 @@ void BaseImageOperation::deinitExecution() BKE_image_release_ibuf(this->m_image, this->m_buffer, NULL); } -void BaseImageOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) +void BaseImageOperation::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2]) { ImBuf *stackbuf = getImBuf(); @@ -170,7 +181,7 @@ void ImageAlphaOperation::executePixelSampled(float output[4], float x, float y, } } -void ImageDepthOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void ImageDepthOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { if (this->m_depthBuffer == NULL) { output[0] = 0.0f; diff --git a/source/blender/compositor/operations/COM_ImageOperation.h b/source/blender/compositor/operations/COM_ImageOperation.h index 206f1509f60..75222559810 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.h +++ b/source/blender/compositor/operations/COM_ImageOperation.h @@ -49,7 +49,9 @@ protected: int m_imagewidth; int m_framenumber; int m_numberOfChannels; - + const RenderData *m_rd; + const char *m_viewName; + BaseImageOperation(); /** * Determine the output resolution. The resolution is retrieved from the Renderer @@ -64,7 +66,8 @@ public: void deinitExecution(); void setImage(Image *image) { this->m_image = image; } void setImageUser(ImageUser *imageuser) { this->m_imageUser = imageuser; } - + void setRenderData(const RenderData *rd) { this->m_rd = rd; } + void setViewName(const char *viewName) { this->m_viewName = viewName; } void setFramenumber(int framenumber) { this->m_framenumber = framenumber; } }; class ImageOperation : public BaseImageOperation { diff --git a/source/blender/compositor/operations/COM_InpaintOperation.cpp b/source/blender/compositor/operations/COM_InpaintOperation.cpp index b64c98be0c7..43b7b30319d 100644 --- a/source/blender/compositor/operations/COM_InpaintOperation.cpp +++ b/source/blender/compositor/operations/COM_InpaintOperation.cpp @@ -83,8 +83,8 @@ float *InpaintSimpleOperation::get_pixel(int x, int y) ASSERT_XY_RANGE(x, y); return &this->m_cached_buffer[ - y * width * COM_NUMBER_OF_CHANNELS + - x * COM_NUMBER_OF_CHANNELS]; + y * width * COM_NUM_CHANNELS_COLOR + + x * COM_NUM_CHANNELS_COLOR]; } int InpaintSimpleOperation::mdist(int x, int y) @@ -241,7 +241,7 @@ void *InpaintSimpleOperation::initializeTileData(rcti *rect) return this->m_cached_buffer; } -void InpaintSimpleOperation::executePixel(float output[4], int x, int y, void *data) +void InpaintSimpleOperation::executePixel(float output[4], int x, int y, void * /*data*/) { this->clamp_xy(x, y); copy_v4_v4(output, this->get_pixel(x, y)); @@ -268,7 +268,7 @@ void InpaintSimpleOperation::deinitExecution() this->m_cached_buffer_ready = false; } -bool InpaintSimpleOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool InpaintSimpleOperation::determineDependingAreaOfInterest(rcti * /*input*/, ReadBufferOperation *readOperation, rcti *output) { if (this->m_cached_buffer_ready) { return false; diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp index 9fb9efe4fc7..72c7512cb23 100644 --- a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp @@ -49,37 +49,27 @@ void *KeyingBlurOperation::initializeTileData(rcti *rect) void KeyingBlurOperation::executePixel(float output[4], int x, int y, void *data) { MemoryBuffer *inputBuffer = (MemoryBuffer *)data; + const int bufferWidth = inputBuffer->getWidth(); float *buffer = inputBuffer->getBuffer(); - - int bufferWidth = inputBuffer->getWidth(); - int bufferHeight = inputBuffer->getHeight(); - - int i, count = 0; - + int count = 0; float average = 0.0f; if (this->m_axis == 0) { - for (i = -this->m_size + 1; i < this->m_size; i++) { - int cx = x + i; - - if (cx >= 0 && cx < bufferWidth) { - int bufferIndex = (y * bufferWidth + cx) * 4; - - average += buffer[bufferIndex]; - count++; - } + const int start = max(0, x - this->m_size + 1), + end = min(bufferWidth, x + this->m_size); + for (int cx = start; cx < end; ++cx) { + int bufferIndex = (y * bufferWidth + cx); + average += buffer[bufferIndex]; + count++; } } else { - for (i = -this->m_size + 1; i < this->m_size; i++) { - int cy = y + i; - - if (cy >= 0 && cy < bufferHeight) { - int bufferIndex = (cy * bufferWidth + x) * 4; - - average += buffer[bufferIndex]; - count++; - } + const int start = max(0, y - this->m_size + 1), + end = min(inputBuffer->getHeight(), y + this->m_size); + for (int cy = start; cy < end; ++cy) { + int bufferIndex = (cy * bufferWidth + x); + average += buffer[bufferIndex]; + count++; } } diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp index d9eb7b588a8..d4ba94f240f 100644 --- a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp @@ -62,7 +62,7 @@ void KeyingClipOperation::executePixel(float output[4], int x, int y, void *data int bufferWidth = inputBuffer->getWidth(); int bufferHeight = inputBuffer->getHeight(); - float value = buffer[(y * bufferWidth + x) * 4]; + float value = buffer[(y * bufferWidth + x)]; bool ok = false; int start_x = max_ff(0, x - delta + 1), @@ -83,7 +83,7 @@ void KeyingClipOperation::executePixel(float output[4], int x, int y, void *data continue; } - int bufferIndex = (cy * bufferWidth + cx) * 4; + int bufferIndex = (cy * bufferWidth + cx); float currentValue = buffer[bufferIndex]; if (fabsf(currentValue - value) < tolerance) { diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp index 17b85847fcf..dd87578ea78 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -188,9 +188,9 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri BLI_freelistN(&edges); if (triangulation->triangles_total) { - rctf *rect; + rcti *rect; rect = triangulation->triangles_AABB = - (rctf *) MEM_callocN(sizeof(rctf) * triangulation->triangles_total, "voronoi triangulation AABB"); + (rcti *) MEM_callocN(sizeof(rcti) * triangulation->triangles_total, "voronoi triangulation AABB"); for (i = 0; i < triangulation->triangles_total; i++, rect++) { int *triangle = triangulation->triangles[i]; @@ -206,11 +206,11 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri minmax_v2v2_v2(min, max, b->co); minmax_v2v2_v2(min, max, c->co); - rect->xmin = min[0]; - rect->ymin = min[1]; + rect->xmin = (int)min[0]; + rect->ymin = (int)min[1]; - rect->xmax = max[0]; - rect->ymax = max[1]; + rect->xmax = (int)max[0] + 1; + rect->ymax = (int)max[1] + 1; } } @@ -224,7 +224,6 @@ void *KeyingScreenOperation::initializeTileData(rcti *rect) int triangles_allocated = 0; int chunk_size = 20; int i; - rctf rect_float; if (this->m_movieClip == NULL) return NULL; @@ -242,14 +241,10 @@ void *KeyingScreenOperation::initializeTileData(rcti *rect) if (!triangulation) return NULL; - BLI_rctf_init(&rect_float, rect->xmin, rect->xmax, rect->ymin, rect->ymax); - tile_data = (TileData *) MEM_callocN(sizeof(TileData), "keying screen tile data"); for (i = 0; i < triangulation->triangles_total; i++) { - bool ok = BLI_rctf_isect(&rect_float, &triangulation->triangles_AABB[i], NULL); - - if (ok) { + if (BLI_rcti_isect(rect, &triangulation->triangles_AABB[i], NULL)) { tile_data->triangles_total++; if (tile_data->triangles_total > triangles_allocated) { @@ -272,7 +267,7 @@ void *KeyingScreenOperation::initializeTileData(rcti *rect) return tile_data; } -void KeyingScreenOperation::deinitializeTileData(rcti *rect, void *data) +void KeyingScreenOperation::deinitializeTileData(rcti * /*rect*/, void *data) { TileData *tile_data = (TileData *) data; @@ -283,7 +278,7 @@ void KeyingScreenOperation::deinitializeTileData(rcti *rect, void *data) MEM_freeN(tile_data); } -void KeyingScreenOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) +void KeyingScreenOperation::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2]) { resolution[0] = 0; resolution[1] = 0; @@ -316,7 +311,7 @@ void KeyingScreenOperation::executePixel(float output[4], int x, int y, void *da for (i = 0; i < tile_data->triangles_total; i++) { int triangle_idx = tile_data->triangles[i]; - rctf *rect = &triangulation->triangles_AABB[triangle_idx]; + rcti *rect = &triangulation->triangles_AABB[triangle_idx]; if (IN_RANGE_INCL(x, rect->xmin, rect->xmax) && IN_RANGE_INCL(y, rect->ymin, rect->ymax)) { int *triangle = triangulation->triangles[triangle_idx]; diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h index 10cf48e57f4..b1a5c0c39c7 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.h +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.h @@ -47,7 +47,7 @@ protected: VoronoiTriangulationPoint *triangulated_points; int (*triangles)[3]; int triangulated_points_total, triangles_total; - rctf *triangles_AABB; + rcti *triangles_AABB; } TriangulationData; typedef struct TileData { diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp index 0e48d5963c6..50ac3b5e055 100644 --- a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp @@ -52,7 +52,7 @@ void LuminanceMatteOperation::executePixelSampled(float output[4], float x, floa this->m_inputImageProgram->readSampled(inColor, x, y, sampler); /* one line thread-friend algorithm: - * output[0] = max(inputValue[3], min(high, max(low, ((inColor[0]-low)/(high-low)))) + * output[0] = max(inputValue[3], min(high, max(low, ((inColor[0] - low) / (high - low)))); */ /* test range */ diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp index 6bf730253e7..d091675286d 100644 --- a/source/blender/compositor/operations/COM_MapUVOperation.cpp +++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp @@ -41,7 +41,7 @@ void MapUVOperation::initExecution() this->m_inputUVProgram = this->getInputSocketReader(1); } -void MapUVOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void MapUVOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { float xy[2] = { x, y }; float uv[2], deriv[2][2], alpha; @@ -53,7 +53,7 @@ void MapUVOperation::executePixelSampled(float output[4], float x, float y, Pixe } /* EWA filtering */ - this->m_inputColorProgram->readFiltered(output, uv[0], uv[1], deriv[0], deriv[1], COM_PS_BILINEAR); + this->m_inputColorProgram->readFiltered(output, uv[0], uv[1], deriv[0], deriv[1]); /* UV to alpha threshold */ const float threshold = this->m_alpha * 0.05f; @@ -83,11 +83,11 @@ bool MapUVOperation::read_uv(float x, float y, float &r_u, float &r_v, float &r_ return false; } else { - float col[4]; - m_inputUVProgram->readSampled(col, x, y, COM_PS_BILINEAR); - r_u = col[0] * m_inputColorProgram->getWidth(); - r_v = col[1] * m_inputColorProgram->getHeight(); - r_alpha = col[2]; + float vector[3]; + m_inputUVProgram->readSampled(vector, x, y, COM_PS_BILINEAR); + r_u = vector[0] * m_inputColorProgram->getWidth(); + r_v = vector[1] * m_inputColorProgram->getHeight(); + r_alpha = vector[2]; return true; } } diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index 8c8ba93327d..220b4e908a6 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2012, Blender Foundation. * * This program is free software; you can redistribute it and/or @@ -127,7 +128,7 @@ void MaskOperation::determineResolution(unsigned int resolution[2], unsigned int } } -void MaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void MaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { const float xy[2] = { (x * this->m_maskWidthInv) + this->m_mask_px_ofs[0], diff --git a/source/blender/compositor/operations/COM_MixOperation.cpp b/source/blender/compositor/operations/COM_MixOperation.cpp index 04025329ad4..d379839a457 100644 --- a/source/blender/compositor/operations/COM_MixOperation.cpp +++ b/source/blender/compositor/operations/COM_MixOperation.cpp @@ -322,9 +322,9 @@ void MixDifferenceOperation::executePixelSampled(float output[4], float x, float value *= inputColor2[3]; } float valuem = 1.0f - value; - output[0] = valuem * inputColor1[0] + value *fabsf(inputColor1[0] - inputColor2[0]); - output[1] = valuem * inputColor1[1] + value *fabsf(inputColor1[1] - inputColor2[1]); - output[2] = valuem * inputColor1[2] + value *fabsf(inputColor1[2] - inputColor2[2]); + output[0] = valuem * inputColor1[0] + value * fabsf(inputColor1[0] - inputColor2[0]); + output[1] = valuem * inputColor1[1] + value * fabsf(inputColor1[1] - inputColor2[1]); + output[2] = valuem * inputColor1[2] + value * fabsf(inputColor1[2] - inputColor2[2]); output[3] = inputColor1[3]; clampIfNeeded(output); diff --git a/source/blender/compositor/operations/COM_MixOperation.h b/source/blender/compositor/operations/COM_MixOperation.h index 479ce161eea..d399edba6e9 100644 --- a/source/blender/compositor/operations/COM_MixOperation.h +++ b/source/blender/compositor/operations/COM_MixOperation.h @@ -76,7 +76,7 @@ public: void setUseValueAlphaMultiply(const bool value) { this->m_valueAlphaMultiply = value; } - bool useValueAlphaMultiply() { return this->m_valueAlphaMultiply; } + inline bool useValueAlphaMultiply() { return this->m_valueAlphaMultiply; } void setUseClamp(bool value) { this->m_useClamp = value; } }; diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp index 447ca1bb4f6..040a0315d69 100644 --- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp @@ -33,7 +33,9 @@ MovieClipAttributeOperation::MovieClipAttributeOperation() : NodeOperation() this->m_attribute = MCA_X; } -void MovieClipAttributeOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void MovieClipAttributeOperation::executePixelSampled(float output[4], + float /*x*/, float /*y*/, + PixelSampler /*sampler*/) { if (!this->m_valueSet) { float loc[2], scale, angle; diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp index 9a184ae1216..1e4821f0cd3 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp @@ -71,7 +71,7 @@ void MovieClipBaseOperation::deinitExecution() } } -void MovieClipBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) +void MovieClipBaseOperation::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2]) { resolution[0] = 0; resolution[1] = 0; @@ -124,9 +124,7 @@ MovieClipAlphaOperation::MovieClipAlphaOperation() : MovieClipBaseOperation() void MovieClipAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - MovieClipBaseOperation::executePixelSampled(output, x, y, sampler); - output[0] = output[3]; - output[1] = 0.0f; - output[2] = 0.0f; - output[3] = 0.0f; + float result[4]; + MovieClipBaseOperation::executePixelSampled(result, x, y, sampler); + output[0] = result[3]; } diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp index 50fabb09dbb..4f34d7fb150 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp @@ -121,7 +121,7 @@ void MovieDistortionOperation::deinitExecution() } -void MovieDistortionOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void MovieDistortionOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { if (this->m_cache != NULL) { diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h index 577712eda56..85f075ab65a 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -36,9 +36,9 @@ extern "C" { class DistortionCache { private: - float m_k1; - float m_k2; - float m_k3; + short m_distortion_model; + float m_k1, m_k2, m_k3; + float m_division_k1, m_division_k2; float m_principal_x; float m_principal_y; float m_pixel_aspect; @@ -59,9 +59,12 @@ public: bool inverted, const int margin[2]) { + this->m_distortion_model = movieclip->tracking.camera.distortion_model; this->m_k1 = movieclip->tracking.camera.k1; this->m_k2 = movieclip->tracking.camera.k2; this->m_k3 = movieclip->tracking.camera.k3; + this->m_division_k1 = movieclip->tracking.camera.division_k1; + this->m_division_k2 = movieclip->tracking.camera.division_k2; this->m_principal_x = movieclip->tracking.camera.principal[0]; this->m_principal_y = movieclip->tracking.camera.principal[1]; this->m_pixel_aspect = movieclip->tracking.camera.pixel_aspect; @@ -101,9 +104,12 @@ public: int calibration_width, int claibration_height, bool inverted) { - return this->m_k1 == movieclip->tracking.camera.k1 && + return this->m_distortion_model == movieclip->tracking.camera.distortion_model && + this->m_k1 == movieclip->tracking.camera.k1 && this->m_k2 == movieclip->tracking.camera.k2 && this->m_k3 == movieclip->tracking.camera.k3 && + this->m_division_k1 == movieclip->tracking.camera.division_k1 && + this->m_division_k2 == movieclip->tracking.camera.division_k2 && this->m_principal_x == movieclip->tracking.camera.principal[0] && this->m_principal_y == movieclip->tracking.camera.principal[1] && this->m_pixel_aspect == movieclip->tracking.camera.pixel_aspect && diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp index 23fba5a7999..b57dd4e32c3 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp @@ -27,18 +27,27 @@ extern "C" { # include "IMB_imbuf_types.h" } -MultilayerBaseOperation::MultilayerBaseOperation(int passindex) : BaseImageOperation() +MultilayerBaseOperation::MultilayerBaseOperation(int passindex, int view) : BaseImageOperation() { this->m_passId = passindex; + this->m_view = view; } + ImBuf *MultilayerBaseOperation::getImBuf() { - RenderPass *rpass = (RenderPass *)BLI_findlink(&this->m_renderlayer->passes, this->m_passId); - if (rpass) { - this->m_imageUser->pass = m_passId; - BKE_image_multilayer_index(this->m_image->rr, this->m_imageUser); - return BaseImageOperation::getImBuf(); + /* temporarily changes the view to get the right ImBuf */ + int view = this->m_imageUser->view; + + this->m_imageUser->view = this->m_view; + this->m_imageUser->pass = this->m_passId; + + if (BKE_image_multilayer_index(this->m_image->rr, this->m_imageUser)) { + ImBuf *ibuf = BaseImageOperation::getImBuf(); + this->m_imageUser->view = view; + return ibuf; } + + this->m_imageUser->view = view; return NULL; } @@ -74,7 +83,7 @@ void MultilayerColorOperation::executePixelSampled(float output[4], float x, flo } } -void MultilayerValueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void MultilayerValueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { if (this->m_imageFloatBuffer == NULL) { output[0] = 0.0f; @@ -91,7 +100,7 @@ void MultilayerValueOperation::executePixelSampled(float output[4], float x, flo } } -void MultilayerVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void MultilayerVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { if (this->m_imageFloatBuffer == NULL) { output[0] = 0.0f; diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.h b/source/blender/compositor/operations/COM_MultilayerImageOperation.h index 37bee1b6a8c..46a9319c373 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.h +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.h @@ -30,6 +30,7 @@ class MultilayerBaseOperation : public BaseImageOperation { private: int m_passId; + int m_view; RenderLayer *m_renderlayer; protected: ImBuf *getImBuf(); @@ -37,13 +38,13 @@ public: /** * Constructor */ - MultilayerBaseOperation(int passindex); + MultilayerBaseOperation(int passindex, int view); void setRenderLayer(RenderLayer *renderlayer) { this->m_renderlayer = renderlayer; } }; class MultilayerColorOperation : public MultilayerBaseOperation { public: - MultilayerColorOperation(int passindex) : MultilayerBaseOperation(passindex) { + MultilayerColorOperation(int passindex, int view) : MultilayerBaseOperation(passindex, view) { this->addOutputSocket(COM_DT_COLOR); } void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); @@ -51,7 +52,7 @@ public: class MultilayerValueOperation : public MultilayerBaseOperation { public: - MultilayerValueOperation(int passindex) : MultilayerBaseOperation(passindex) { + MultilayerValueOperation(int passindex, int view) : MultilayerBaseOperation(passindex, view) { this->addOutputSocket(COM_DT_VALUE); } void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); @@ -59,7 +60,7 @@ public: class MultilayerVectorOperation : public MultilayerBaseOperation { public: - MultilayerVectorOperation(int passindex) : MultilayerBaseOperation(passindex) { + MultilayerVectorOperation(int passindex, int view) : MultilayerBaseOperation(passindex, view) { this->addOutputSocket(COM_DT_VECTOR); } void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cpp b/source/blender/compositor/operations/COM_NormalizeOperation.cpp index f81b50e6836..504470f1a7e 100644 --- a/source/blender/compositor/operations/COM_NormalizeOperation.cpp +++ b/source/blender/compositor/operations/COM_NormalizeOperation.cpp @@ -60,7 +60,7 @@ void NormalizeOperation::deinitExecution() NodeOperation::deinitMutex(); } -bool NormalizeOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool NormalizeOperation::determineDependingAreaOfInterest(rcti * /*input*/, ReadBufferOperation *readOperation, rcti *output) { rcti imageInput; if (this->m_cachedInstance) return false; @@ -104,7 +104,7 @@ void *NormalizeOperation::initializeTileData(rcti *rect) if ((value < minv) && (value >= -BLENDER_ZMAX)) { minv = value; } - bc += 4; + bc ++; } minmult->x = minv; @@ -118,7 +118,7 @@ void *NormalizeOperation::initializeTileData(rcti *rect) return this->m_cachedInstance; } -void NormalizeOperation::deinitializeTileData(rcti *rect, void *data) +void NormalizeOperation::deinitializeTileData(rcti * /*rect*/, void * /*data*/) { /* pass */ } diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl index 00b3825d8b3..cbd05cbec17 100644 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl @@ -80,10 +80,10 @@ __kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only ima } //KERNEL --- DEFOCUS /VARIABLESIZEBOKEHBLUR --- -__kernel void defocusKernel(__read_only image2d_t inputImage, __read_only image2d_t bokehImage, - __read_only image2d_t inputSize, - __write_only image2d_t output, int2 offsetInput, int2 offsetOutput, - int step, int maxBlurScalar, float threshold, float scalar, int2 dimension, int2 offset) +__kernel void defocusKernel(__read_only image2d_t inputImage, __read_only image2d_t bokehImage, + __read_only image2d_t inputSize, + __write_only image2d_t output, int2 offsetInput, int2 offsetOutput, + int step, int maxBlurScalar, float threshold, float scalar, int2 dimension, int2 offset) { float4 color = {1.0f, 0.0f, 0.0f, 1.0f}; int2 coords = {get_global_id(0), get_global_id(1)}; @@ -212,8 +212,8 @@ __kernel void erodeKernel(__read_only image2d_t inputImage, __write_only image2 // KERNEL --- DIRECTIONAL BLUR --- __kernel void directionalBlurKernel(__read_only image2d_t inputImage, __write_only image2d_t output, - int2 offsetOutput, int iterations, float scale, float rotation, float2 translate, - float2 center, int2 offset) + int2 offsetOutput, int iterations, float scale, float rotation, float2 translate, + float2 center, int2 offset) { int2 coords = {get_global_id(0), get_global_id(1)}; coords += offset; @@ -250,3 +250,66 @@ __kernel void directionalBlurKernel(__read_only image2d_t inputImage, __write_o write_imagef(output, coords, col); } + +// KERNEL --- GAUSSIAN BLUR --- +__kernel void gaussianXBlurOperationKernel(__read_only image2d_t inputImage, + int2 offsetInput, + __write_only image2d_t output, + int2 offsetOutput, + int filter_size, + int2 dimension, + __global float *gausstab, + int2 offset) +{ + float4 color = {0.0f, 0.0f, 0.0f, 0.0f}; + int2 coords = {get_global_id(0), get_global_id(1)}; + coords += offset; + const int2 realCoordinate = coords + offsetOutput; + int2 inputCoordinate = realCoordinate - offsetInput; + float weight = 0.0f; + + int xmin = max(realCoordinate.x - filter_size, 0) - offsetInput.x; + int xmax = min(realCoordinate.x + filter_size + 1, dimension.x) - offsetInput.x; + + for (int nx = xmin, i = max(filter_size - realCoordinate.x, 0); nx < xmax; ++nx, ++i) { + float w = gausstab[i]; + inputCoordinate.x = nx; + color += read_imagef(inputImage, SAMPLER_NEAREST, inputCoordinate) * w; + weight += w; + } + + color *= (1.0f / weight); + + write_imagef(output, coords, color); +} + +__kernel void gaussianYBlurOperationKernel(__read_only image2d_t inputImage, + int2 offsetInput, + __write_only image2d_t output, + int2 offsetOutput, + int filter_size, + int2 dimension, + __global float *gausstab, + int2 offset) +{ + float4 color = {0.0f, 0.0f, 0.0f, 0.0f}; + int2 coords = {get_global_id(0), get_global_id(1)}; + coords += offset; + const int2 realCoordinate = coords + offsetOutput; + int2 inputCoordinate = realCoordinate - offsetInput; + float weight = 0.0f; + + int ymin = max(realCoordinate.y - filter_size, 0) - offsetInput.y; + int ymax = min(realCoordinate.y + filter_size + 1, dimension.y) - offsetInput.y; + + for (int ny = ymin, i = max(filter_size - realCoordinate.y, 0); ny < ymax; ++ny, ++i) { + float w = gausstab[i]; + inputCoordinate.y = ny; + color += read_imagef(inputImage, SAMPLER_NEAREST, inputCoordinate) * w; + weight += w; + } + + color *= (1.0f / weight); + + write_imagef(output, coords, color); +} diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp new file mode 100644 index 00000000000..7786359c06a --- /dev/null +++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp @@ -0,0 +1,322 @@ +/* + * Copyright 2015, 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 + * Lukas Tönne + * Dalai Felinto + */ + +#include "COM_OutputFileOperation.h" +#include "COM_OutputFileMultiViewOperation.h" + +#include <string.h> +#include "BLI_listbase.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "BKE_image.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_scene.h" + +#include "DNA_color_types.h" +#include "MEM_guardedalloc.h" + +extern "C" { +#include "IMB_imbuf.h" +#include "IMB_colormanagement.h" +#include "IMB_imbuf_types.h" +} + +/************************************ OpenEXR Singlelayer Multiview *****************************************/ + +OutputOpenExrSingleLayerMultiViewOperation::OutputOpenExrSingleLayerMultiViewOperation( + const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path, + const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings, + const char *viewName) + : OutputSingleLayerOperation(rd, tree, datatype, format, path, viewSettings, displaySettings, viewName) +{ +} + +void *OutputOpenExrSingleLayerMultiViewOperation::get_handle(const char *filename) +{ + size_t width = this->getWidth(); + size_t height = this->getHeight(); + SceneRenderView *srv; + + if (width != 0 && height != 0) { + void *exrhandle; + + exrhandle = IMB_exr_get_handle_name(filename); + + if (!BKE_scene_multiview_is_render_view_first(this->m_rd, this->m_viewName)) + return exrhandle; + + IMB_exr_clear_channels(exrhandle); + + for (srv = (SceneRenderView *)this->m_rd->views.first; srv; srv = srv->next) { + if (BKE_scene_multiview_is_render_view_active(this->m_rd, srv) == false) + continue; + + IMB_exr_add_view(exrhandle, srv->name); + add_exr_channels(exrhandle, NULL, this->m_datatype, srv->name, width, false, NULL); + } + + BLI_make_existing_file(filename); + + /* prepare the file with all the channels */ + + if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_format->exr_codec, NULL) == 0) { + printf("Error Writing Singlelayer Multiview Openexr\n"); + IMB_exr_close(exrhandle); + } + else { + IMB_exr_clear_channels(exrhandle); + return exrhandle; + } + } + return NULL; +} + +void OutputOpenExrSingleLayerMultiViewOperation::deinitExecution() +{ + unsigned int width = this->getWidth(); + unsigned int height = this->getHeight(); + + if (width != 0 && height != 0) { + void *exrhandle; + Main *bmain = G.main; /* TODO, have this passed along */ + char filename[FILE_MAX]; + + BKE_image_path_from_imtype( + filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_OPENEXR, + (this->m_rd->scemode & R_EXTENSION) != 0, true, NULL); + + exrhandle = this->get_handle(filename); + add_exr_channels(exrhandle, NULL, this->m_datatype, this->m_viewName, width, + this->m_format->depth == R_IMF_CHAN_DEPTH_16, this->m_outputBuffer); + + /* memory can only be freed after we write all views to the file */ + this->m_outputBuffer = NULL; + this->m_imageInput = NULL; + + /* ready to close the file */ + if (BKE_scene_multiview_is_render_view_last(this->m_rd, this->m_viewName)) { + IMB_exr_write_channels(exrhandle); + + /* free buffer memory for all the views */ + free_exr_channels(exrhandle, this->m_rd, NULL, this->m_datatype); + + /* remove exr handle and data */ + IMB_exr_close(exrhandle); + } + } +} + +/************************************ OpenEXR Multilayer Multiview *****************************************/ + +OutputOpenExrMultiLayerMultiViewOperation::OutputOpenExrMultiLayerMultiViewOperation( + const RenderData *rd, const bNodeTree *tree, const char *path, + char exr_codec, bool exr_half_float, const char *viewName) + : OutputOpenExrMultiLayerOperation(rd, tree, path, exr_codec, exr_half_float, viewName) +{ +} + +void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename) +{ + unsigned int width = this->getWidth(); + unsigned int height = this->getHeight(); + + if (width != 0 && height != 0) { + + void *exrhandle; + SceneRenderView *srv; + + /* get a new global handle */ + exrhandle = IMB_exr_get_handle_name(filename); + + if (!BKE_scene_multiview_is_render_view_first(this->m_rd, this->m_viewName)) + return exrhandle; + + IMB_exr_clear_channels(exrhandle); + + /* check renderdata for amount of views */ + for (srv = (SceneRenderView *) this->m_rd->views.first; srv; srv = srv->next) { + + if (BKE_scene_multiview_is_render_view_active(this->m_rd, srv) == false) + continue; + + IMB_exr_add_view(exrhandle, srv->name); + + for (unsigned int i = 0; i < this->m_layers.size(); ++i) + add_exr_channels(exrhandle, this->m_layers[i].name, this->m_layers[i].datatype, + srv->name, width, this->m_exr_half_float, NULL); + } + + BLI_make_existing_file(filename); + + /* prepare the file with all the channels for the header */ + if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_exr_codec, NULL) == 0) { + printf("Error Writing Multilayer Multiview Openexr\n"); + IMB_exr_close(exrhandle); + } + else { + IMB_exr_clear_channels(exrhandle); + return exrhandle; + } + } + return NULL; +} + +void OutputOpenExrMultiLayerMultiViewOperation::deinitExecution() +{ + unsigned int width = this->getWidth(); + unsigned int height = this->getHeight(); + + if (width != 0 && height != 0) { + void *exrhandle; + Main *bmain = G.main; /* TODO, have this passed along */ + char filename[FILE_MAX]; + + BKE_image_path_from_imtype( + filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER, + (this->m_rd->scemode & R_EXTENSION) != 0, true, NULL); + + exrhandle = this->get_handle(filename); + + for (unsigned int i = 0; i < this->m_layers.size(); ++i) + add_exr_channels(exrhandle, this->m_layers[i].name, this->m_layers[i].datatype, this->m_viewName, + width, this->m_exr_half_float, this->m_layers[i].outputBuffer); + + for (unsigned int i = 0; i < this->m_layers.size(); ++i) { + /* memory can only be freed after we write all views to the file */ + this->m_layers[i].outputBuffer = NULL; + this->m_layers[i].imageInput = NULL; + } + + /* ready to close the file */ + if (BKE_scene_multiview_is_render_view_last(this->m_rd, this->m_viewName)) { + IMB_exr_write_channels(exrhandle); + + /* free buffer memory for all the views */ + for (unsigned int i = 0; i < this->m_layers.size(); ++i) { + free_exr_channels(exrhandle, this->m_rd, this->m_layers[i].name, this->m_layers[i].datatype); + } + + IMB_exr_close(exrhandle); + } + } +} + + +/******************************** Stereo3D ******************************/ + +OutputStereoOperation::OutputStereoOperation( + const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path, + const char *name, const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings, + const char *viewName) + : OutputSingleLayerOperation(rd, tree, datatype, format, path, viewSettings, displaySettings, viewName) +{ + BLI_strncpy(this->m_name, name, sizeof(this->m_name)); + this->m_channels = get_datatype_size(datatype); +} + +void *OutputStereoOperation::get_handle(const char *filename) +{ + size_t width = this->getWidth(); + size_t height = this->getHeight(); + const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; + size_t i; + + if (width != 0 && height != 0) { + void *exrhandle; + + exrhandle = IMB_exr_get_handle_name(filename); + + if (!BKE_scene_multiview_is_render_view_first(this->m_rd, this->m_viewName)) + return exrhandle; + + IMB_exr_clear_channels(exrhandle); + + for (i = 0; i < 2; i++) + IMB_exr_add_view(exrhandle, names[i]); + + return exrhandle; + } + return NULL; +} + +void OutputStereoOperation::deinitExecution() +{ + unsigned int width = this->getWidth(); + unsigned int height = this->getHeight(); + + if (width != 0 && height != 0) { + void *exrhandle; + + exrhandle = this->get_handle(this->m_path); + float *buf = this->m_outputBuffer; + + /* populate single EXR channel with view data */ + IMB_exr_add_channel(exrhandle, NULL, this->m_name, this->m_viewName, 1, this->m_channels * width * height, buf, + this->m_format->depth == R_IMF_CHAN_DEPTH_16); + + this->m_imageInput = NULL; + this->m_outputBuffer = NULL; + + /* create stereo ibuf */ + if (BKE_scene_multiview_is_render_view_last(this->m_rd, this->m_viewName)) { + ImBuf *ibuf[3] = {NULL}; + const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; + Main *bmain = G.main; /* TODO, have this passed along */ + char filename[FILE_MAX]; + int i; + + /* get rectf from EXR */ + for (i = 0; i < 2; i++) { + float *rectf = IMB_exr_channel_rect(exrhandle, NULL, this->m_name, names[i]); + ibuf[i] = IMB_allocImBuf(width, height, this->m_format->planes, 0); + + ibuf[i]->channels = this->m_channels; + ibuf[i]->rect_float = rectf; + ibuf[i]->mall |= IB_rectfloat; + ibuf[i]->dither = this->m_rd->dither_intensity; + + /* do colormanagement in the individual views, so it doesn't need to do in the stereo */ + IMB_colormanagement_imbuf_for_write(ibuf[i], true, false, this->m_viewSettings, + this->m_displaySettings, this->m_format); + IMB_prepare_write_ImBuf(IMB_isfloat(ibuf[i]), ibuf[i]); + } + + /* create stereo buffer */ + ibuf[2] = IMB_stereo3d_ImBuf(this->m_format, ibuf[0], ibuf[1]); + + BKE_image_path_from_imformat( + filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format, + (this->m_rd->scemode & R_EXTENSION) != 0, true, NULL); + + BKE_imbuf_write(ibuf[2], filename, this->m_format); + + /* imbuf knows which rects are not part of ibuf */ + for (i = 0; i < 3; i++) + IMB_freeImBuf(ibuf[i]); + + IMB_exr_close(exrhandle); + } + } +} diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h new file mode 100644 index 00000000000..25ed8816399 --- /dev/null +++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h @@ -0,0 +1,74 @@ +/* + * Copyright 2015, 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 + * Lukas Tönne + * Dalai Felinto + */ + +#ifndef _COM_OutputFileMultiViewOperation_h +#define _COM_OutputFileMultiViewOperation_h +#include "COM_NodeOperation.h" + +#include "BLI_rect.h" +#include "BLI_path_util.h" + +#include "DNA_color_types.h" + +#include "intern/openexr/openexr_multi.h" + +class OutputOpenExrSingleLayerMultiViewOperation : public OutputSingleLayerOperation { +private: +public: + OutputOpenExrSingleLayerMultiViewOperation(const RenderData *rd, const bNodeTree *tree, DataType datatype, + ImageFormatData *format, const char *path, + const ColorManagedViewSettings *viewSettings, + const ColorManagedDisplaySettings *displaySettings, + const char *viewName); + + void *get_handle(const char *filename); + void deinitExecution(); +}; + +/* Writes inputs into OpenEXR multilayer channels. */ +class OutputOpenExrMultiLayerMultiViewOperation : public OutputOpenExrMultiLayerOperation { +private: +public: + OutputOpenExrMultiLayerMultiViewOperation(const RenderData *rd, const bNodeTree *tree, const char *path, + char exr_codec, bool exr_half_float, const char *viewName); + + void *get_handle(const char *filename); + void deinitExecution(); +}; + +/**/ +class OutputStereoOperation : public OutputSingleLayerOperation { +private: + char m_name[FILE_MAX]; + size_t m_channels; +public: + OutputStereoOperation(const RenderData *rd, const bNodeTree *tree, DataType datatype, + struct ImageFormatData *format, const char *path, const char *name, + const ColorManagedViewSettings *viewSettings, + const ColorManagedDisplaySettings *displaySettings, const char *viewName); + void *get_handle(const char *filename); + void deinitExecution(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp index 92e8f309ea1..fdf5a0b48cf 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp @@ -29,6 +29,7 @@ #include "BKE_image.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_scene.h" #include "DNA_color_types.h" @@ -39,7 +40,61 @@ extern "C" { # include "IMB_imbuf_types.h" } -static int get_datatype_size(DataType datatype) +void add_exr_channels(void *exrhandle, const char *layerName, const DataType datatype, + const char *viewName, const size_t width, bool use_half_float, float *buf) +{ + /* create channels */ + switch (datatype) { + case COM_DT_VALUE: + IMB_exr_add_channel(exrhandle, layerName, "V", viewName, 1, width, buf ? buf : NULL, use_half_float); + break; + case COM_DT_VECTOR: + IMB_exr_add_channel(exrhandle, layerName, "X", viewName, 3, 3 * width, buf ? buf : NULL, use_half_float); + IMB_exr_add_channel(exrhandle, layerName, "Y", viewName, 3, 3 * width, buf ? buf + 1 : NULL, use_half_float); + IMB_exr_add_channel(exrhandle, layerName, "Z", viewName, 3, 3 * width, buf ? buf + 2 : NULL, use_half_float); + break; + case COM_DT_COLOR: + IMB_exr_add_channel(exrhandle, layerName, "R", viewName, 4, 4 * width, buf ? buf : NULL, use_half_float); + IMB_exr_add_channel(exrhandle, layerName, "G", viewName, 4, 4 * width, buf ? buf + 1 : NULL, use_half_float); + IMB_exr_add_channel(exrhandle, layerName, "B", viewName, 4, 4 * width, buf ? buf + 2 : NULL, use_half_float); + IMB_exr_add_channel(exrhandle, layerName, "A", viewName, 4, 4 * width, buf ? buf + 3 : NULL, use_half_float); + break; + default: + break; + } +} + +void free_exr_channels(void *exrhandle, const RenderData *rd, const char *layerName, const DataType datatype) +{ + SceneRenderView *srv; + + /* check renderdata for amount of views */ + for (srv = (SceneRenderView *) rd->views.first; srv; srv = srv->next) { + float *rect = NULL; + + if (BKE_scene_multiview_is_render_view_active(rd, srv) == false) + continue; + + /* the pointer is stored in the first channel of each datatype */ + switch (datatype) { + case COM_DT_VALUE: + rect = IMB_exr_channel_rect(exrhandle, layerName, "V", srv->name); + break; + case COM_DT_VECTOR: + rect = IMB_exr_channel_rect(exrhandle, layerName, "X", srv->name); + break; + case COM_DT_COLOR: + rect = IMB_exr_channel_rect(exrhandle, layerName, "R", srv->name); + break; + default: + break; + } + if (rect) + MEM_freeN(rect); + } +} + +int get_datatype_size(DataType datatype) { switch (datatype) { case COM_DT_VALUE: return 1; @@ -94,7 +149,7 @@ static void write_buffer_rect(rcti *rect, const bNodeTree *tree, OutputSingleLayerOperation::OutputSingleLayerOperation( const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path, - const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings) + const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings, const char *viewName) { this->m_rd = rd; this->m_tree = tree; @@ -110,6 +165,7 @@ OutputSingleLayerOperation::OutputSingleLayerOperation( this->m_viewSettings = viewSettings; this->m_displaySettings = displaySettings; + this->m_viewName = viewName; } void OutputSingleLayerOperation::initExecution() @@ -118,7 +174,7 @@ void OutputSingleLayerOperation::initExecution() this->m_outputBuffer = init_buffer(this->getWidth(), this->getHeight(), this->m_datatype); } -void OutputSingleLayerOperation::executeRegion(rcti *rect, unsigned int tileNumber) +void OutputSingleLayerOperation::executeRegion(rcti *rect, unsigned int /*tileNumber*/) { write_buffer_rect(rect, this->m_tree, this->m_imageInput, this->m_outputBuffer, this->getWidth(), this->m_datatype); } @@ -131,6 +187,7 @@ void OutputSingleLayerOperation::deinitExecution() ImBuf *ibuf = IMB_allocImBuf(this->getWidth(), this->getHeight(), this->m_format->planes, 0); Main *bmain = G.main; /* TODO, have this passed along */ char filename[FILE_MAX]; + const char *suffix; ibuf->channels = size; ibuf->rect_float = this->m_outputBuffer; @@ -140,9 +197,12 @@ void OutputSingleLayerOperation::deinitExecution() IMB_colormanagement_imbuf_for_write(ibuf, true, false, m_viewSettings, m_displaySettings, this->m_format); - BKE_makepicstring(filename, this->m_path, bmain->name, this->m_rd->cfra, - this->m_format, (this->m_rd->scemode & R_EXTENSION) != 0, true); - + suffix = BKE_scene_multiview_view_suffix_get(this->m_rd, this->m_viewName); + + BKE_image_path_from_imformat( + filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format, + (this->m_rd->scemode & R_EXTENSION) != 0, true, suffix); + if (0 == BKE_imbuf_write(ibuf, filename, this->m_format)) printf("Cannot save Node File Output to %s\n", filename); else @@ -154,6 +214,7 @@ void OutputSingleLayerOperation::deinitExecution() this->m_imageInput = NULL; } +/******************************* MultiLayer *******************************/ OutputOpenExrLayer::OutputOpenExrLayer(const char *name_, DataType datatype_, bool use_layer_) { @@ -167,13 +228,16 @@ OutputOpenExrLayer::OutputOpenExrLayer(const char *name_, DataType datatype_, bo } OutputOpenExrMultiLayerOperation::OutputOpenExrMultiLayerOperation( - const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec) + const RenderData *rd, const bNodeTree *tree, const char *path, + char exr_codec, bool exr_half_float, const char *viewName) { this->m_rd = rd; this->m_tree = tree; BLI_strncpy(this->m_path, path, sizeof(this->m_path)); this->m_exr_codec = exr_codec; + this->m_exr_half_float = exr_half_float; + this->m_viewName = viewName; } void OutputOpenExrMultiLayerOperation::add_layer(const char *name, DataType datatype, bool use_layer) @@ -193,7 +257,7 @@ void OutputOpenExrMultiLayerOperation::initExecution() } } -void OutputOpenExrMultiLayerOperation::executeRegion(rcti *rect, unsigned int tileNumber) +void OutputOpenExrMultiLayerOperation::executeRegion(rcti *rect, unsigned int /*tileNumber*/) { for (unsigned int i = 0; i < this->m_layers.size(); ++i) { OutputOpenExrLayer &layer = this->m_layers[i]; @@ -209,55 +273,26 @@ void OutputOpenExrMultiLayerOperation::deinitExecution() if (width != 0 && height != 0) { Main *bmain = G.main; /* TODO, have this passed along */ char filename[FILE_MAX]; + const char *suffix; void *exrhandle = IMB_exr_get_handle(); - - BKE_makepicstring_from_type(filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER, - (this->m_rd->scemode & R_EXTENSION) != 0, true); + + suffix = BKE_scene_multiview_view_suffix_get(this->m_rd, this->m_viewName); + BKE_image_path_from_imtype( + filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER, + (this->m_rd->scemode & R_EXTENSION) != 0, true, suffix); BLI_make_existing_file(filename); - + for (unsigned int i = 0; i < this->m_layers.size(); ++i) { OutputOpenExrLayer &layer = this->m_layers[i]; if (!layer.imageInput) continue; /* skip unconnected sockets */ - char channelname[EXR_TOT_MAXNAME]; - BLI_strncpy(channelname, this->m_layers[i].name, sizeof(channelname) - 2); - char *channelname_ext = channelname + strlen(channelname); - - float *buf = this->m_layers[i].outputBuffer; - - /* create channels */ - switch (this->m_layers[i].datatype) { - case COM_DT_VALUE: - strcpy(channelname_ext, ".V"); - IMB_exr_add_channel(exrhandle, 0, channelname, 1, width, buf); - break; - case COM_DT_VECTOR: - strcpy(channelname_ext, ".X"); - IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3 * width, buf); - strcpy(channelname_ext, ".Y"); - IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3 * width, buf + 1); - strcpy(channelname_ext, ".Z"); - IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3 * width, buf + 2); - break; - case COM_DT_COLOR: - strcpy(channelname_ext, ".R"); - IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf); - strcpy(channelname_ext, ".G"); - IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf + 1); - strcpy(channelname_ext, ".B"); - IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf + 2); - strcpy(channelname_ext, ".A"); - IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf + 3); - break; - default: - break; - } - + add_exr_channels(exrhandle, this->m_layers[i].name, this->m_layers[i].datatype, "", width, + this->m_exr_half_float, this->m_layers[i].outputBuffer); } /* when the filename has no permissions, this can fail */ - if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_exr_codec)) { + if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_exr_codec, NULL)) { IMB_exr_write_channels(exrhandle); } else { @@ -277,3 +312,4 @@ void OutputOpenExrMultiLayerOperation::deinitExecution() } } } + diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h index 03278c5b149..93468977a66 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.h +++ b/source/blender/compositor/operations/COM_OutputFileOperation.h @@ -34,7 +34,7 @@ /* Writes the image to a single-layer file. */ class OutputSingleLayerOperation : public NodeOperation { -private: +protected: const RenderData *m_rd; const bNodeTree *m_tree; @@ -47,12 +47,14 @@ private: const ColorManagedViewSettings *m_viewSettings; const ColorManagedDisplaySettings *m_displaySettings; + + const char *m_viewName; public: OutputSingleLayerOperation(const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path, - const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings); + const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings, const char *viewName); void executeRegion(rcti *rect, unsigned int tileNumber); - bool isOutputOperation(bool rendering) const { return true; } + bool isOutputOperation(bool /*rendering*/) const { return true; } void initExecution(); void deinitExecution(); const CompositorPriority getRenderPriority() const { return COM_PRIORITY_LOW; } @@ -75,7 +77,7 @@ struct OutputOpenExrLayer { /* Writes inputs into OpenEXR multilayer channels. */ class OutputOpenExrMultiLayerOperation : public NodeOperation { -private: +protected: typedef std::vector<OutputOpenExrLayer> LayerList; const RenderData *m_rd; @@ -83,15 +85,18 @@ private: char m_path[FILE_MAX]; char m_exr_codec; + bool m_exr_half_float; LayerList m_layers; + const char *m_viewName; public: - OutputOpenExrMultiLayerOperation(const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec); + OutputOpenExrMultiLayerOperation(const RenderData *rd, const bNodeTree *tree, const char *path, + char exr_codec, bool exr_half_float, const char *viewName); void add_layer(const char *name, DataType datatype, bool use_layer); void executeRegion(rcti *rect, unsigned int tileNumber); - bool isOutputOperation(bool rendering) const { return true; } + bool isOutputOperation(bool /*rendering*/) const { return true; } void initExecution(); void deinitExecution(); const CompositorPriority getRenderPriority() const { return COM_PRIORITY_LOW; } @@ -99,4 +104,9 @@ public: bool isFileOutputOperation() const { return true; } }; +void add_exr_channels(void *exrhandle, const char *layerName, const DataType datatype, const char *viewName, + const size_t width, bool use_half_float, float *buf); +void free_exr_channels(void *exrhandle, const RenderData *rd, const char *layerName, const DataType datatype); +int get_datatype_size(DataType datatype); + #endif diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp index fe272000b6e..fb8730c9fa0 100644 --- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp +++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp @@ -135,7 +135,7 @@ void *PlaneCornerPinMaskOperation::initializeTileData(rcti *rect) getInputSocketReader(3) }; float corners[4][2]; readCornersFromSockets(rect, readers, corners); - calculateCorners(corners, true); + calculateCorners(corners, true, 0); m_corners_ready = true; } @@ -194,8 +194,7 @@ void *PlaneCornerPinWarpImageOperation::initializeTileData(rcti *rect) getInputSocketReader(4) }; float corners[4][2]; readCornersFromSockets(rect, readers, corners); - calculateCorners(corners, true); - calculatePerspectiveMatrix(); + calculateCorners(corners, true, 0); m_corners_ready = true; } diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp index c507b4cfa98..1145abd076a 100644 --- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp +++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp @@ -56,36 +56,38 @@ PlaneDistortWarpImageOperation::PlaneDistortWarpImageOperation() : this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); this->addOutputSocket(COM_DT_COLOR); this->m_pixelReader = NULL; + this->m_motion_blur_samples = 1; + this->m_motion_blur_shutter = 0.5f; this->setComplex(true); } -void PlaneDistortWarpImageOperation::calculateCorners(const float corners[4][2], bool normalized) +void PlaneDistortWarpImageOperation::calculateCorners(const float corners[4][2], + bool normalized, + int sample) { + BLI_assert(sample < this->m_motion_blur_samples); + const int width = this->m_pixelReader->getWidth(); + const int height = this->m_pixelReader->getHeight(); + float frame_corners[4][2] = {{0.0f, 0.0f}, + {(float) width, 0.0f}, + {(float) width, (float) height}, + {0.0f, (float) height}}; + MotionSample *sample_data = &this->m_samples[sample]; if (normalized) { for (int i = 0; i < 4; i++) { - this->m_frameSpaceCorners[i][0] = corners[i][0] * this->getWidth(); - this->m_frameSpaceCorners[i][1] = corners[i][1] * this->getHeight(); + sample_data->frameSpaceCorners[i][0] = corners[i][0] * this->getWidth(); + sample_data->frameSpaceCorners[i][1] = corners[i][1] * this->getHeight(); } } else { for (int i = 0; i < 4; i++) { - this->m_frameSpaceCorners[i][0] = corners[i][0]; - this->m_frameSpaceCorners[i][1] = corners[i][1]; + sample_data->frameSpaceCorners[i][0] = corners[i][0]; + sample_data->frameSpaceCorners[i][1] = corners[i][1]; } } -} - -void PlaneDistortWarpImageOperation::calculatePerspectiveMatrix() -{ - const int width = this->m_pixelReader->getWidth(); - const int height = this->m_pixelReader->getHeight(); - float frame_corners[4][2] = {{0.0f, 0.0f}, - {(float) width, 0.0f}, - {(float) width, (float) height}, - {0.0f, (float) height}}; - BKE_tracking_homography_between_two_quads(this->m_frameSpaceCorners, + BKE_tracking_homography_between_two_quads(sample_data->frameSpaceCorners, frame_corners, - this->m_perspectiveMatrix); + sample_data->perspectiveMatrix); } void PlaneDistortWarpImageOperation::initExecution() @@ -98,37 +100,47 @@ void PlaneDistortWarpImageOperation::deinitExecution() this->m_pixelReader = NULL; } -void PlaneDistortWarpImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void PlaneDistortWarpImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { - float xy[2] = {x, y}; float uv[2]; float deriv[2][2]; - - pixelTransform(xy, uv, deriv); - - m_pixelReader->readFiltered(output, uv[0], uv[1], deriv[0], deriv[1], COM_PS_BILINEAR); -} - -void PlaneDistortWarpImageOperation::pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2]) -{ - warpCoord(xy[0], xy[1], m_perspectiveMatrix, r_uv, r_deriv); + if (this->m_motion_blur_samples == 1) { + warpCoord(x, y, this->m_samples[0].perspectiveMatrix, uv, deriv); + m_pixelReader->readFiltered(output, + uv[0], uv[1], + deriv[0], deriv[1]); + } + else { + zero_v4(output); + for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) { + float color[4]; + warpCoord(x, y, this->m_samples[sample].perspectiveMatrix, uv, deriv); + m_pixelReader->readFiltered(color, + uv[0], uv[1], + deriv[0], deriv[1]); + add_v4_v4(output, color); + } + mul_v4_fl(output, 1.0f / (float)this->m_motion_blur_samples); + } } bool PlaneDistortWarpImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { - float UVs[4][2]; - float deriv[2][2]; - - /* TODO(sergey): figure out proper way to do this. */ - warpCoord(input->xmin - 2, input->ymin - 2, this->m_perspectiveMatrix, UVs[0], deriv); - warpCoord(input->xmax + 2, input->ymin - 2, this->m_perspectiveMatrix, UVs[1], deriv); - warpCoord(input->xmax + 2, input->ymax + 2, this->m_perspectiveMatrix, UVs[2], deriv); - warpCoord(input->xmin - 2, input->ymax + 2, this->m_perspectiveMatrix, UVs[3], deriv); - float min[2], max[2]; INIT_MINMAX2(min, max); - for (int i = 0; i < 4; i++) { - minmax_v2v2_v2(min, max, UVs[i]); + + for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) { + float UVs[4][2]; + float deriv[2][2]; + MotionSample *sample_data = &this->m_samples[sample]; + /* TODO(sergey): figure out proper way to do this. */ + warpCoord(input->xmin - 2, input->ymin - 2, sample_data->perspectiveMatrix, UVs[0], deriv); + warpCoord(input->xmax + 2, input->ymin - 2, sample_data->perspectiveMatrix, UVs[1], deriv); + warpCoord(input->xmax + 2, input->ymax + 2, sample_data->perspectiveMatrix, UVs[2], deriv); + warpCoord(input->xmin - 2, input->ymax + 2, sample_data->perspectiveMatrix, UVs[3], deriv); + for (int i = 0; i < 4; i++) { + minmax_v2v2_v2(min, max, UVs[i]); + } } rcti newInput; @@ -151,20 +163,26 @@ PlaneDistortMaskOperation::PlaneDistortMaskOperation() : /* Currently hardcoded to 8 samples. */ m_osa = 8; + this->m_motion_blur_samples = 1; + this->m_motion_blur_shutter = 0.5f; } -void PlaneDistortMaskOperation::calculateCorners(const float corners[4][2], bool normalized) +void PlaneDistortMaskOperation::calculateCorners(const float corners[4][2], + bool normalized, + int sample) { + BLI_assert(sample < this->m_motion_blur_samples); + MotionSample *sample_data = &this->m_samples[sample]; if (normalized) { for (int i = 0; i < 4; i++) { - this->m_frameSpaceCorners[i][0] = corners[i][0] * this->getWidth(); - this->m_frameSpaceCorners[i][1] = corners[i][1] * this->getHeight(); + sample_data->frameSpaceCorners[i][0] = corners[i][0] * this->getWidth(); + sample_data->frameSpaceCorners[i][1] = corners[i][1] * this->getHeight(); } } else { for (int i = 0; i < 4; i++) { - this->m_frameSpaceCorners[i][0] = corners[i][0]; - this->m_frameSpaceCorners[i][1] = corners[i][1]; + sample_data->frameSpaceCorners[i][0] = corners[i][0]; + sample_data->frameSpaceCorners[i][1] = corners[i][1]; } } } @@ -174,21 +192,47 @@ void PlaneDistortMaskOperation::initExecution() BLI_jitter_init(m_jitter, m_osa); } -void PlaneDistortMaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void PlaneDistortMaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { float point[2]; - int inside_counter = 0; - for (int sample = 0; sample < this->m_osa; sample++) { - point[0] = x + this->m_jitter[sample][0]; - point[1] = y + this->m_jitter[sample][1]; - - if (isect_point_tri_v2(point, this->m_frameSpaceCorners[0], this->m_frameSpaceCorners[1], this->m_frameSpaceCorners[2]) || - isect_point_tri_v2(point, this->m_frameSpaceCorners[0], this->m_frameSpaceCorners[2], this->m_frameSpaceCorners[3])) + if (this->m_motion_blur_samples == 1) { + MotionSample *sample_data = &this->m_samples[0]; + for (int sample = 0; sample < this->m_osa; sample++) { + point[0] = x + this->m_jitter[sample][0]; + point[1] = y + this->m_jitter[sample][1]; + if (isect_point_tri_v2(point, sample_data->frameSpaceCorners[0], + sample_data->frameSpaceCorners[1], + sample_data->frameSpaceCorners[2]) || + isect_point_tri_v2(point, sample_data->frameSpaceCorners[0], + sample_data->frameSpaceCorners[2], + sample_data->frameSpaceCorners[3])) + { + inside_counter++; + } + } + output[0] = (float)inside_counter / this->m_osa; + } + else { + for (int motion_sample = 0; + motion_sample < this->m_motion_blur_samples; + ++motion_sample) { - inside_counter++; + MotionSample *sample_data = &this->m_samples[motion_sample]; + for (int osa_sample = 0; osa_sample < this->m_osa; ++osa_sample) { + point[0] = x + this->m_jitter[osa_sample][0]; + point[1] = y + this->m_jitter[osa_sample][1]; + if (isect_point_tri_v2(point, sample_data->frameSpaceCorners[0], + sample_data->frameSpaceCorners[1], + sample_data->frameSpaceCorners[2]) || + isect_point_tri_v2(point, sample_data->frameSpaceCorners[0], + sample_data->frameSpaceCorners[2], + sample_data->frameSpaceCorners[3])) + { + inside_counter++; + } + } } + output[0] = (float)inside_counter / (this->m_osa * this->m_motion_blur_samples); } - - output[0] = (float) inside_counter / this->m_osa; } diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h index ee2874c6b46..fc5dd1ff7d8 100644 --- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h +++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h @@ -33,43 +33,72 @@ #include "BLI_listbase.h" #include "BLI_string.h" +#define PLANE_DISTORT_MAX_SAMPLES 64 class PlaneDistortWarpImageOperation : public NodeOperation { protected: + struct MotionSample { + float frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */ + float perspectiveMatrix[3][3]; + }; SocketReader *m_pixelReader; - float m_frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */ - float m_perspectiveMatrix[3][3]; + MotionSample m_samples[PLANE_DISTORT_MAX_SAMPLES]; + int m_motion_blur_samples; + float m_motion_blur_shutter; public: PlaneDistortWarpImageOperation(); - void calculateCorners(const float corners[4][2], bool normalized); - void calculatePerspectiveMatrix(); + void calculateCorners(const float corners[4][2], + bool normalized, + int sample); void initExecution(); void deinitExecution(); void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); - void pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2]); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void setMotionBlurSamples(int samples) { + BLI_assert(samples <= PLANE_DISTORT_MAX_SAMPLES); + this->m_motion_blur_samples = samples; + } + void setMotionBlurShutter(float shutter) { + this->m_motion_blur_shutter = shutter; + } }; class PlaneDistortMaskOperation : public NodeOperation { protected: + struct MotionSample { + float frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */ + }; int m_osa; + MotionSample m_samples[PLANE_DISTORT_MAX_SAMPLES]; float m_jitter[32][2]; - float m_frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */ + int m_motion_blur_samples; + float m_motion_blur_shutter; public: PlaneDistortMaskOperation(); - - void calculateCorners(const float corners[4][2], bool normalized); - + + void calculateCorners(const float corners[4][2], + bool normalized, + int sample); + void initExecution(); - + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + + void setMotionBlurSamples(int samples) { + BLI_assert(samples <= PLANE_DISTORT_MAX_SAMPLES); + this->m_motion_blur_samples = samples; + } + void setMotionBlurShutter(float shutter) { + this->m_motion_blur_shutter = shutter; + } }; #endif diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp b/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp index fec39cbfde0..a56aa0cbaa6 100644 --- a/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp +++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp @@ -46,47 +46,41 @@ PlaneTrackCommon::PlaneTrackCommon() this->m_planeTrackName[0] = '\0'; } -void PlaneTrackCommon::readCornersFromTrack(float corners[4][2]) +void PlaneTrackCommon::readCornersFromTrack(float corners[4][2], float frame) { MovieTracking *tracking; MovieTrackingObject *object; if (!this->m_movieClip) return; - + tracking = &this->m_movieClip->tracking; - + object = BKE_tracking_object_get_named(tracking, this->m_trackingObjectName); if (object) { MovieTrackingPlaneTrack *plane_track; - plane_track = BKE_tracking_plane_track_get_named(tracking, object, this->m_planeTrackName); - if (plane_track) { - MovieTrackingPlaneMarker *plane_marker; - int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber); - - plane_marker = BKE_tracking_plane_marker_get(plane_track, clip_framenr); - copy_v2_v2(corners[0], plane_marker->corners[0]); - copy_v2_v2(corners[1], plane_marker->corners[1]); - copy_v2_v2(corners[2], plane_marker->corners[2]); - copy_v2_v2(corners[3], plane_marker->corners[3]); + float clip_framenr = + BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, + frame); + BKE_tracking_plane_marker_get_subframe_corners(plane_track, + clip_framenr, + corners); } } } -void PlaneTrackCommon::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) +void PlaneTrackCommon::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2]) { resolution[0] = 0; resolution[1] = 0; - + if (this->m_movieClip) { int width, height; MovieClipUser user = {0}; - BKE_movieclip_user_set_frame(&user, this->m_framenumber); BKE_movieclip_get_size(this->m_movieClip, &user, &width, &height); - resolution[0] = width; resolution[1] = height; } @@ -98,10 +92,21 @@ void PlaneTrackCommon::determineResolution(unsigned int resolution[2], unsigned void PlaneTrackMaskOperation::initExecution() { PlaneDistortMaskOperation::initExecution(); - float corners[4][2]; - readCornersFromTrack(corners); - calculateCorners(corners, true); + if (this->m_motion_blur_samples == 1) { + readCornersFromTrack(corners, this->m_framenumber); + calculateCorners(corners, true, 0); + } + else { + const float frame = (float)this->m_framenumber - this->m_motion_blur_shutter; + const float frame_step = (this->m_motion_blur_shutter * 2.0f) / this->m_motion_blur_samples; + float frame_iter = frame; + for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) { + readCornersFromTrack(corners, frame_iter); + calculateCorners(corners, true, sample); + frame_iter += frame_step; + } + } } /* ******** PlaneTrackWarpImageOperation ******** */ @@ -109,9 +114,20 @@ void PlaneTrackMaskOperation::initExecution() void PlaneTrackWarpImageOperation::initExecution() { PlaneDistortWarpImageOperation::initExecution(); - + /* TODO(sergey): De-duplicate with mask operation. */ float corners[4][2]; - readCornersFromTrack(corners); - calculateCorners(corners, true); - calculatePerspectiveMatrix(); + if (this->m_motion_blur_samples == 1) { + readCornersFromTrack(corners, this->m_framenumber); + calculateCorners(corners, true, 0); + } + else { + const float frame = (float)this->m_framenumber - this->m_motion_blur_shutter; + const float frame_step = (this->m_motion_blur_shutter * 2.0f) / this->m_motion_blur_samples; + float frame_iter = frame; + for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) { + readCornersFromTrack(corners, frame_iter); + calculateCorners(corners, true, sample); + frame_iter += frame_step; + } + } } diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.h b/source/blender/compositor/operations/COM_PlaneTrackOperation.h index 3c5dd783542..41761493e12 100644 --- a/source/blender/compositor/operations/COM_PlaneTrackOperation.h +++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.h @@ -43,7 +43,7 @@ protected: /* note: this class is not an operation itself (to prevent virtual inheritance issues) * implementation classes must make wrappers to use these methods, see below. */ - void readCornersFromTrack(float corners[4][2]); + void readCornersFromTrack(float corners[4][2], float frame); void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); public: @@ -68,7 +68,7 @@ public: void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) { PlaneTrackCommon::determineResolution(resolution, preferredResolution); - + unsigned int temp[2]; NodeOperation::determineResolution(temp, resolution); } @@ -81,13 +81,12 @@ public: PlaneDistortWarpImageOperation(), PlaneTrackCommon() {} - + void initExecution(); - + void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) { PlaneTrackCommon::determineResolution(resolution, preferredResolution); - unsigned int temp[2]; NodeOperation::determineResolution(temp, resolution); } diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cpp b/source/blender/compositor/operations/COM_PreviewOperation.cpp index 69290cd7c3c..aa667884de6 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.cpp +++ b/source/blender/compositor/operations/COM_PreviewOperation.cpp @@ -85,7 +85,7 @@ void PreviewOperation::deinitExecution() this->m_input = NULL; } -void PreviewOperation::executeRegion(rcti *rect, unsigned int tileNumber) +void PreviewOperation::executeRegion(rcti *rect, unsigned int /*tileNumber*/) { int offset; float color[4]; diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h index 3e97acec7bb..5da7a25ac5d 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.h +++ b/source/blender/compositor/operations/COM_PreviewOperation.h @@ -45,7 +45,7 @@ public: PreviewOperation(const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings); void verifyPreview(bNodeInstanceHash *previews, bNodeInstanceKey key); - bool isOutputOperation(bool rendering) const { return !G.background; } + bool isOutputOperation(bool /*rendering*/) const { return !G.background; } void initExecution(); void deinitExecution(); const CompositorPriority getRenderPriority() const; diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp index 7f6079c55aa..02d1809efbb 100644 --- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp @@ -40,7 +40,7 @@ void ProjectorLensDistortionOperation::initExecution() this->m_inputProgram = this->getInputSocketReader(0); } -void *ProjectorLensDistortionOperation::initializeTileData(rcti *rect) +void *ProjectorLensDistortionOperation::initializeTileData(rcti * /*rect*/) { updateDispersion(); void *buffer = this->m_inputProgram->initializeTileData(NULL); diff --git a/source/blender/compositor/operations/COM_QualityStepHelper.cpp b/source/blender/compositor/operations/COM_QualityStepHelper.cpp index d99d6f28eff..4d9c15f9747 100644 --- a/source/blender/compositor/operations/COM_QualityStepHelper.cpp +++ b/source/blender/compositor/operations/COM_QualityStepHelper.cpp @@ -37,15 +37,15 @@ void QualityStepHelper::initExecution(QualityHelper helper) case COM_QUALITY_HIGH: default: this->m_step = 1; - this->m_offsetadd = 4; + this->m_offsetadd = 1; break; case COM_QUALITY_MEDIUM: this->m_step = 2; - this->m_offsetadd = 8; + this->m_offsetadd = 2; break; case COM_QUALITY_LOW: this->m_step = 3; - this->m_offsetadd = 12; + this->m_offsetadd = 3; break; } break; diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp index 47d5fc6bcca..6dbe132257a 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp @@ -24,15 +24,15 @@ #include "COM_WriteBufferOperation.h" #include "COM_defines.h" -ReadBufferOperation::ReadBufferOperation() : NodeOperation() +ReadBufferOperation::ReadBufferOperation(DataType datatype) : NodeOperation() { - this->addOutputSocket(COM_DT_COLOR); + this->addOutputSocket(datatype); this->m_single_value = false; this->m_offset = 0; this->m_buffer = NULL; } -void *ReadBufferOperation::initializeTileData(rcti *rect) +void *ReadBufferOperation::initializeTileData(rcti * /*rect*/) { return m_buffer; } @@ -58,11 +58,19 @@ void ReadBufferOperation::executePixelSampled(float output[4], float x, float y, /* write buffer has a single value stored at (0,0) */ m_buffer->read(output, 0, 0); } - else if (sampler == COM_PS_NEAREST) { - m_buffer->read(output, x, y); - } else { - m_buffer->readBilinear(output, x, y); + switch (sampler) { + case COM_PS_NEAREST: + m_buffer->read(output, x, y); + break; + case COM_PS_BILINEAR: + default: + m_buffer->readBilinear(output, x, y); + break; + case COM_PS_BICUBIC: + m_buffer->readBilinear(output, x, y); + break; + } } } @@ -81,7 +89,7 @@ void ReadBufferOperation::executePixelExtend(float output[4], float x, float y, } } -void ReadBufferOperation::executePixelFiltered(float output[4], float x, float y, float dx[2], float dy[2], PixelSampler sampler) +void ReadBufferOperation::executePixelFiltered(float output[4], float x, float y, float dx[2], float dy[2]) { if (m_single_value) { /* write buffer has a single value stored at (0,0) */ @@ -90,7 +98,7 @@ void ReadBufferOperation::executePixelFiltered(float output[4], float x, float y else { const float uv[2] = { x, y }; const float deriv[2][2] = { {dx[0], dx[1]}, {dy[0], dy[1]} }; - m_buffer->readEWA(output, uv, deriv, sampler); + m_buffer->readEWA(output, uv, deriv); } } diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.h b/source/blender/compositor/operations/COM_ReadBufferOperation.h index 569920d51ef..cd706ed0b75 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.h +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.h @@ -25,6 +25,7 @@ #include "COM_NodeOperation.h" #include "COM_MemoryProxy.h" +#include "COM_MemoryBuffer.h" class ReadBufferOperation : public NodeOperation { private: @@ -33,7 +34,7 @@ private: unsigned int m_offset; MemoryBuffer *m_buffer; public: - ReadBufferOperation(); + ReadBufferOperation(DataType datetype); void setMemoryProxy(MemoryProxy *memoryProxy) { this->m_memoryProxy = memoryProxy; } MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; } void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); @@ -42,7 +43,7 @@ public: void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void executePixelExtend(float output[4], float x, float y, PixelSampler sampler, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y); - void executePixelFiltered(float output[4], float x, float y, float dx[2], float dy[2], PixelSampler sampler); + void executePixelFiltered(float output[4], float x, float y, float dx[2], float dy[2]); const bool isReadBufferOperation() const { return true; } void setOffset(unsigned int offset) { this->m_offset = offset; } unsigned int getOffset() const { return this->m_offset; } diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cpp b/source/blender/compositor/operations/COM_RenderLayersProg.cpp index 06f4f6d77cf..1a7e775113b 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersProg.cpp @@ -23,6 +23,7 @@ #include "COM_RenderLayersProg.h" #include "BLI_listbase.h" +#include "BKE_scene.h" #include "DNA_scene_types.h" extern "C" { @@ -57,11 +58,10 @@ void RenderLayersBaseProg::initExecution() if (srl) { RenderLayer *rl = RE_GetRenderLayer(rr, srl->name); - if (rl && rl->rectf) { - this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_renderpass); - + if (rl) { + this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_renderpass, this->m_viewName); if (this->m_inputBuffer == NULL && this->m_renderpass == SCE_PASS_COMBINED) { - this->m_inputBuffer = rl->rectf; + this->m_inputBuffer = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, this->m_viewName); } } } @@ -111,15 +111,6 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi BLI_bicubic_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y); break; } - - if (this->m_elementsize == 1) { - output[1] = 0.0f; - output[2] = 0.0f; - output[3] = 0.0f; - } - else if (this->m_elementsize == 3) { - output[3] = 1.0f; - } } void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) @@ -144,8 +135,39 @@ void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y int iy = y - dy; #endif +#ifndef NDEBUG + { + const DataType data_type = this->getOutputSocket()->getDataType(); + int actual_element_size = this->m_elementsize; + int expected_element_size; + if (data_type == COM_DT_VALUE) { + expected_element_size = 1; + } + else if (data_type == COM_DT_VECTOR) { + expected_element_size = 3; + } + else if (data_type == COM_DT_COLOR) { + expected_element_size = 4; + } + else { + BLI_assert(!"Something horribly wrong just happened"); + } + BLI_assert(expected_element_size == actual_element_size); + } +#endif + if (this->m_inputBuffer == NULL) { - zero_v4(output); + int elemsize = this->m_elementsize; + if (elemsize == 1) { + output[0] = 0.0f; + } + else if (elemsize == 3) { + zero_v3(output); + } + else { + BLI_assert(elemsize == 4); + zero_v4(output); + } } else { doInterpolation(output, x, y, sampler); @@ -157,7 +179,7 @@ void RenderLayersBaseProg::deinitExecution() this->m_inputBuffer = NULL; } -void RenderLayersBaseProg::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) +void RenderLayersBaseProg::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2]) { Scene *sce = this->getScene(); Render *re = (sce) ? RE_GetRender(sce->id.name) : NULL; @@ -173,7 +195,7 @@ void RenderLayersBaseProg::determineResolution(unsigned int resolution[2], unsig SceneRenderLayer *srl = (SceneRenderLayer *)BLI_findlink(&sce->r.layers, getLayerId()); if (srl) { RenderLayer *rl = RE_GetRenderLayer(rr, srl->name); - if (rl && rl->rectf) { + if (rl) { resolution[0] = rl->rectx; resolution[1] = rl->recty; } @@ -192,6 +214,19 @@ RenderLayersAOOperation::RenderLayersAOOperation() : RenderLayersBaseProg(SCE_PA this->addOutputSocket(COM_DT_COLOR); } + +void RenderLayersAOOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +{ + float *inputBuffer = this->getInputBuffer(); + if (inputBuffer == NULL) { + zero_v3(output); + } + else { + doInterpolation(output, x, y, sampler); + } + output[3] = 1.0f; +} + /* ******** Render Layers Alpha Operation ******** */ RenderLayersAlphaProg::RenderLayersAlphaProg() : RenderLayersBaseProg(SCE_PASS_COMBINED, 4) @@ -204,15 +239,12 @@ void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, float float *inputBuffer = this->getInputBuffer(); if (inputBuffer == NULL) { - zero_v4(output); + output[0] = 0.0f; } else { float temp[4]; doInterpolation(temp, x, y, sampler); output[0] = temp[3]; - output[1] = 0.0f; - output[2] = 0.0f; - output[3] = 0.0f; } } @@ -227,7 +259,7 @@ RenderLayersColorOperation::RenderLayersColorOperation() : RenderLayersBaseProg( RenderLayersCyclesOperation::RenderLayersCyclesOperation(int pass) : RenderLayersBaseProg(pass, 3) { - this->addOutputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VECTOR); } /* ******** Render Layers Depth Operation ******** */ @@ -237,7 +269,7 @@ RenderLayersDepthProg::RenderLayersDepthProg() : RenderLayersBaseProg(SCE_PASS_Z this->addOutputSocket(COM_DT_VALUE); } -void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { int ix = x; int iy = y; @@ -245,16 +277,10 @@ void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) { output[0] = 0.0f; - output[1] = 0.0f; - output[2] = 0.0f; - output[3] = 0.0f; } else { unsigned int offset = (iy * this->getWidth() + ix); output[0] = inputBuffer[offset]; - output[1] = 0.0f; - output[2] = 0.0f; - output[3] = 0.0f; } } @@ -262,21 +288,21 @@ void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float RenderLayersDiffuseOperation::RenderLayersDiffuseOperation() : RenderLayersBaseProg(SCE_PASS_DIFFUSE, 3) { - this->addOutputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VECTOR); } /* ******** Render Layers Emit Operation ******** */ RenderLayersEmitOperation::RenderLayersEmitOperation() : RenderLayersBaseProg(SCE_PASS_EMIT, 3) { - this->addOutputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VECTOR); } /* ******** Render Layers Environment Operation ******** */ RenderLayersEnvironmentOperation::RenderLayersEnvironmentOperation() : RenderLayersBaseProg(SCE_PASS_ENVIRONMENT, 3) { - this->addOutputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VECTOR); } /* ******** Render Layers Image Operation ******** */ @@ -290,7 +316,7 @@ RenderLayersColorProg::RenderLayersColorProg() : RenderLayersBaseProg(SCE_PASS_C RenderLayersIndirectOperation::RenderLayersIndirectOperation() : RenderLayersBaseProg(SCE_PASS_INDIRECT, 3) { - this->addOutputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VECTOR); } /* ******** Render Layers Material Index Operation ******** */ @@ -325,28 +351,28 @@ RenderLayersObjectIndexOperation::RenderLayersObjectIndexOperation() : RenderLay RenderLayersReflectionOperation::RenderLayersReflectionOperation() : RenderLayersBaseProg(SCE_PASS_REFLECT, 3) { - this->addOutputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VECTOR); } /* ******** Render Layers Refraction Operation ******** */ RenderLayersRefractionOperation::RenderLayersRefractionOperation() : RenderLayersBaseProg(SCE_PASS_REFRACT, 3) { - this->addOutputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VECTOR); } /* ******** Render Layers Shadow Operation ******** */ RenderLayersShadowOperation::RenderLayersShadowOperation() : RenderLayersBaseProg(SCE_PASS_SHADOW, 3) { - this->addOutputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VECTOR); } /* ******** Render Layers Specular Operation ******** */ RenderLayersSpecularOperation::RenderLayersSpecularOperation() : RenderLayersBaseProg(SCE_PASS_SPEC, 3) { - this->addOutputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VECTOR); } /* ******** Render Layers Speed Operation ******** */ @@ -362,3 +388,29 @@ RenderLayersUVOperation::RenderLayersUVOperation() : RenderLayersBaseProg(SCE_PA { this->addOutputSocket(COM_DT_VECTOR); } + +/* ******** Debug Render Layers Cycles Operation ******** */ + +#ifdef WITH_CYCLES_DEBUG + +RenderLayersCyclesDebugOperation::RenderLayersCyclesDebugOperation( + int pass, + int debug_pass_type) + : RenderLayersBaseProg(pass, RE_debug_pass_num_channels_get(debug_pass_type)) +{ + switch (m_elementsize) { + case 1: + this->addOutputSocket(COM_DT_VALUE); + break; + case 3: + this->addOutputSocket(COM_DT_VECTOR); + break; + case 4: + this->addOutputSocket(COM_DT_COLOR); + break; + default: + BLI_assert(!"Unkown debug pass type element size."); + } +} + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.h b/source/blender/compositor/operations/COM_RenderLayersProg.h index 554e27eb579..89eb2a6954d 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.h +++ b/source/blender/compositor/operations/COM_RenderLayersProg.h @@ -41,7 +41,7 @@ extern "C" { * @todo: rename to operation. */ class RenderLayersBaseProg : public NodeOperation { -private: +protected: /** * Reference to the scene object. */ @@ -51,7 +51,12 @@ private: * layerId of the layer where this operation needs to get its data from */ short m_layerId; - + + /** + * viewName of the view to use (unless another view is specified by the node + */ + const char *m_viewName; + /** * cached instance to the float buffer inside the layer */ @@ -69,7 +74,6 @@ private: */ const RenderData *m_rd; -protected: /** * Constructor */ @@ -97,6 +101,8 @@ public: void setRenderData(const RenderData *rd) { this->m_rd = rd; } void setLayerId(short layerId) { this->m_layerId = layerId; } short getLayerId() { return this->m_layerId; } + void setViewName(const char *viewName) { this->m_viewName = viewName; } + const char *getViewName() { return this->m_viewName; } void initExecution(); void deinitExecution(); void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); @@ -105,6 +111,7 @@ public: class RenderLayersAOOperation : public RenderLayersBaseProg { public: RenderLayersAOOperation(); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class RenderLayersAlphaProg : public RenderLayersBaseProg { @@ -205,4 +212,12 @@ public: RenderLayersUVOperation(); }; +#ifdef WITH_CYCLES_DEBUG +class RenderLayersCyclesDebugOperation : public RenderLayersBaseProg { +public: + RenderLayersCyclesDebugOperation(int pass, + int debug_pass_type); +}; +#endif + #endif diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp index 23e8ce86fd9..117ae743ee7 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cpp +++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp @@ -279,7 +279,7 @@ bool ScaleFixedSizeOperation::determineDependingAreaOfInterest(rcti *input, Read return BaseScaleOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } -void ScaleFixedSizeOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) +void ScaleFixedSizeOperation::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2]) { unsigned int nr[2]; nr[0] = this->m_newWidth; diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp index ad9b761da45..acd76fa79a8 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp @@ -70,7 +70,7 @@ void ScreenLensDistortionOperation::initExecution() } } -void *ScreenLensDistortionOperation::initializeTileData(rcti *rect) +void *ScreenLensDistortionOperation::initializeTileData(rcti * /*rect*/) { void *buffer = this->m_inputProgram->initializeTileData(NULL); @@ -208,7 +208,7 @@ void ScreenLensDistortionOperation::determineUV(float result[6], float x, float get_delta(uv_dot, m_k4[2], uv, result + 4); } -bool ScreenLensDistortionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool ScreenLensDistortionOperation::determineDependingAreaOfInterest(rcti * /*input*/, ReadBufferOperation *readOperation, rcti *output) { rcti newInputValue; newInputValue.xmin = 0; diff --git a/source/blender/compositor/operations/COM_SetColorOperation.cpp b/source/blender/compositor/operations/COM_SetColorOperation.cpp index 94a863e628b..1a362bc55e2 100644 --- a/source/blender/compositor/operations/COM_SetColorOperation.cpp +++ b/source/blender/compositor/operations/COM_SetColorOperation.cpp @@ -27,7 +27,9 @@ SetColorOperation::SetColorOperation() : NodeOperation() this->addOutputSocket(COM_DT_COLOR); } -void SetColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void SetColorOperation::executePixelSampled(float output[4], + float /*x*/, float /*y*/, + PixelSampler /*sampler*/) { copy_v4_v4(output, this->m_color); } diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.cpp b/source/blender/compositor/operations/COM_SetSamplerOperation.cpp index be72ffd0336..7057ecb14c1 100644 --- a/source/blender/compositor/operations/COM_SetSamplerOperation.cpp +++ b/source/blender/compositor/operations/COM_SetSamplerOperation.cpp @@ -37,7 +37,7 @@ void SetSamplerOperation::deinitExecution() this->m_reader = NULL; } -void SetSamplerOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void SetSamplerOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { this->m_reader->readSampled(output, x, y, this->m_sampler); } diff --git a/source/blender/compositor/operations/COM_SetValueOperation.cpp b/source/blender/compositor/operations/COM_SetValueOperation.cpp index 51e09a63051..b6cfb760a98 100644 --- a/source/blender/compositor/operations/COM_SetValueOperation.cpp +++ b/source/blender/compositor/operations/COM_SetValueOperation.cpp @@ -27,7 +27,9 @@ SetValueOperation::SetValueOperation() : NodeOperation() this->addOutputSocket(COM_DT_VALUE); } -void SetValueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void SetValueOperation::executePixelSampled(float output[4], + float /*x*/, float /*y*/, + PixelSampler /*sampler*/) { output[0] = this->m_value; } diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.cpp b/source/blender/compositor/operations/COM_SetVectorOperation.cpp index 17212d78e15..1b0327683a9 100644 --- a/source/blender/compositor/operations/COM_SetVectorOperation.cpp +++ b/source/blender/compositor/operations/COM_SetVectorOperation.cpp @@ -28,12 +28,13 @@ SetVectorOperation::SetVectorOperation() : NodeOperation() this->addOutputSocket(COM_DT_VECTOR); } -void SetVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void SetVectorOperation::executePixelSampled(float output[4], + float /*x*/, float /*y*/, + PixelSampler /*sampler*/) { output[0] = this->m_x; output[1] = this->m_y; output[2] = this->m_z; - output[3] = this->m_w; } void SetVectorOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) diff --git a/source/blender/compositor/operations/COM_SplitOperation.cpp b/source/blender/compositor/operations/COM_SplitOperation.cpp index 367c7eefa25..cd2166591bc 100644 --- a/source/blender/compositor/operations/COM_SplitOperation.cpp +++ b/source/blender/compositor/operations/COM_SplitOperation.cpp @@ -56,7 +56,7 @@ void SplitOperation::deinitExecution() this->m_image2Input = NULL; } -void SplitOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void SplitOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { int perc = this->m_xSplit ? this->m_splitPercentage * this->getWidth() / 100.0f : this->m_splitPercentage * this->getHeight() / 100.0f; bool image1 = this->m_xSplit ? x > perc : y > perc; diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp index bcef652a8b5..a681583809c 100644 --- a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp +++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp @@ -50,34 +50,52 @@ void SunBeamsOperation::initExecution() * For a target point (x,y) the sector should be chosen such that * ``u >= v >= 0`` * This removes the need to handle all sorts of special cases. + * + * Template parameters: + * fxu : buffer increment in x for sector u+1 + * fxv : buffer increment in x for sector v+1 + * fyu : buffer increment in y for sector u+1 + * fyv : buffer increment in y for sector v+1 */ -template <int fxx, int fxy, int fyx, int fyy> +template <int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator { /* utility functions implementing the matrix transform to/from sector space */ - - static inline void buffer_to_sector(int x, int y, int &u, int &v) + + static inline void buffer_to_sector(const float source[2], int x, int y, int &u, int &v) { - u = x * fxx + y * fyx; - v = x * fxy + y * fyy; + int x0 = (int)source[0]; + int y0 = (int)source[1]; + x -= x0; + y -= y0; + u = x * fxu + y * fyu; + v = x * fxv + y * fyv; } - static inline void buffer_to_sector(float x, float y, float &u, float &v) + static inline void buffer_to_sector(const float source[2], float x, float y, float &u, float &v) { - u = x * fxx + y * fyx; - v = x * fxy + y * fyy; + int x0 = (int)source[0]; + int y0 = (int)source[1]; + x -= (float)x0; + y -= (float)y0; + u = x * fxu + y * fyu; + v = x * fxv + y * fyv; } - static inline void sector_to_buffer(int u, int v, int &x, int &y) + static inline void sector_to_buffer(const float source[2], int u, int v, int &x, int &y) { - x = u * fxx + v * fxy; - y = u * fyx + v * fyy; + int x0 = (int)source[0]; + int y0 = (int)source[1]; + x = x0 + u * fxu + v * fxv; + y = y0 + u * fyu + v * fyv; } - static inline void sector_to_buffer(float u, float v, float &x, float &y) + static inline void sector_to_buffer(const float source[2], float u, float v, float &x, float &y) { - x = u * fxx + v * fxy; - y = u * fyx + v * fyy; + int x0 = (int)source[0]; + int y0 = (int)source[1]; + x = (float)x0 + u * fxu + v * fxv; + y = (float)y0 + u * fyu + v * fyv; } /** @@ -91,12 +109,12 @@ struct BufferLineAccumulator { * \param num Total steps in the loop * \param v, dv Vertical offset in sector space, for line offset perpendicular to the loop axis */ - static float *init_buffer_iterator(MemoryBuffer *input, const float source[2], const float pt_ofs[2], + static float *init_buffer_iterator(MemoryBuffer *input, const float source[2], const float co[2], float dist_min, float dist_max, int &x, int &y, int &num, float &v, float &dv, float &falloff_factor) { float pu, pv; - buffer_to_sector(pt_ofs[0], pt_ofs[1], pu, pv); + buffer_to_sector(source, co[0], co[1], pu, pv); /* line angle */ float tan_phi = pv / pu; @@ -113,13 +131,11 @@ struct BufferLineAccumulator { int end = (int)ceilf(umin); num = end - start; - sector_to_buffer(end, (int)ceilf(v), x, y); - x += (int)source[0]; - y += (int)source[1]; + sector_to_buffer(source, end, (int)ceilf(v), x, y); falloff_factor = dist_max > dist_min ? dr / (float)(dist_max - dist_min) : 0.0f; - float *iter = input->getBuffer() + COM_NUMBER_OF_CHANNELS * (x + input->getWidth() * y); + float *iter = input->getBuffer() + COM_NUM_CHANNELS_COLOR * (x + input->getWidth() * y); return iter; } @@ -130,7 +146,7 @@ struct BufferLineAccumulator { * The loop runs backwards(!) over the primary sector space axis u, i.e. increasing distance to pt. * After each step it decrements v by dv < 1, adding a buffer shift when necessary. */ - static void eval(MemoryBuffer *input, float output[4], const float pt_ofs[2], const float source[2], + static void eval(MemoryBuffer *input, float output[4], const float co[2], const float source[2], float dist_min, float dist_max) { rcti rect = *input->getRect(); @@ -139,14 +155,16 @@ struct BufferLineAccumulator { float v, dv; float falloff_factor; float border[4]; - - if ((int)pt_ofs[0] == 0 && (int)pt_ofs[1] == 0) { - copy_v4_v4(output, input->getBuffer() + COM_NUMBER_OF_CHANNELS * ((int)source[0] + input->getWidth() * (int)source[1])); + + zero_v4(output); + + if ((int)(co[0] - source[0]) == 0 && (int)(co[1] - source[1]) == 0) { + copy_v4_v4(output, input->getBuffer() + COM_NUM_CHANNELS_COLOR * ((int)source[0] + input->getWidth() * (int)source[1])); return; } /* initialise the iteration variables */ - float *buffer = init_buffer_iterator(input, source, pt_ofs, dist_min, dist_max, x, y, num, v, dv, falloff_factor); + float *buffer = init_buffer_iterator(input, source, co, dist_min, dist_max, x, y, num, v, dv, falloff_factor); zero_v3(border); border[3] = 1.0f; @@ -178,18 +196,18 @@ struct BufferLineAccumulator { */ /* decrement u */ - x -= fxx; - y -= fyx; - buffer -= (fxx + fyx * buffer_width) * COM_NUMBER_OF_CHANNELS; + x -= fxu; + y -= fyu; + buffer -= (fxu + fyu * buffer_width) * COM_NUM_CHANNELS_COLOR; /* decrement v (in steps of dv < 1) */ v_local -= dv; if (v_local < 0.0f) { v_local += 1.0f; - x -= fxy; - y -= fyy; - buffer -= (fxy + fyy * buffer_width) * COM_NUMBER_OF_CHANNELS; + x -= fxv; + y -= fyv; + buffer -= (fxv + fyv * buffer_width) * COM_NUM_CHANNELS_COLOR; } } @@ -233,21 +251,21 @@ static void accumulate_line(MemoryBuffer *input, float output[4], const float co if (pt_ofs[0] > 0.0f) { if (pt_ofs[1] > 0.0f) { /* 2 */ - BufferLineAccumulator<0, 1, 1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<0, 1, 1, 0>::eval(input, output, co, source, dist_min, dist_max); } else { /* 7 */ - BufferLineAccumulator<0, 1, -1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<0, 1, -1, 0>::eval(input, output, co, source, dist_min, dist_max); } } else { if (pt_ofs[1] > 0.0f) { /* 3 */ - BufferLineAccumulator<0, -1, 1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<0, -1, 1, 0>::eval(input, output, co, source, dist_min, dist_max); } else { /* 6 */ - BufferLineAccumulator<0, -1, -1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<0, -1, -1, 0>::eval(input, output, co, source, dist_min, dist_max); } } } @@ -255,27 +273,27 @@ static void accumulate_line(MemoryBuffer *input, float output[4], const float co if (pt_ofs[0] > 0.0f) { if (pt_ofs[1] > 0.0f) { /* 1 */ - BufferLineAccumulator< 1, 0, 0, 1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator< 1, 0, 0, 1>::eval(input, output, co, source, dist_min, dist_max); } else { /* 8 */ - BufferLineAccumulator< 1, 0, 0, -1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator< 1, 0, 0, -1>::eval(input, output, co, source, dist_min, dist_max); } } else { if (pt_ofs[1] > 0.0f) { /* 4 */ - BufferLineAccumulator<-1, 0, 0, 1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<-1, 0, 0, 1>::eval(input, output, co, source, dist_min, dist_max); } else { /* 5 */ - BufferLineAccumulator<-1, 0, 0, -1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<-1, 0, 0, -1>::eval(input, output, co, source, dist_min, dist_max); } } } } -void *SunBeamsOperation::initializeTileData(rcti *rect) +void *SunBeamsOperation::initializeTileData(rcti * /*rect*/) { void *buffer = getInputOperation(0)->initializeTileData(NULL); return buffer; diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp index ede767cbff7..c75c4040823 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.cpp +++ b/source/blender/compositor/operations/COM_TextureOperation.cpp @@ -23,8 +23,11 @@ #include "COM_TextureOperation.h" #include "BLI_listbase.h" +#include "BLI_threads.h" #include "BKE_image.h" +static ThreadMutex mutex_lock = BLI_MUTEX_INITIALIZER; + TextureBaseOperation::TextureBaseOperation() : SingleThreadedOperation() { this->addInputSocket(COM_DT_VECTOR); //offset @@ -77,12 +80,9 @@ void TextureBaseOperation::determineResolution(unsigned int resolution[2], unsig void TextureAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - TextureBaseOperation::executePixelSampled(output, x, y, sampler); - output[0] = output[3]; - output[1] = 0.0f; - output[2] = 0.0f; - output[3] = 0.0f; -} + float color[4]; + TextureBaseOperation::executePixelSampled(color, x, y, sampler); + output[0] = color[3];} void TextureBaseOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { @@ -103,7 +103,12 @@ void TextureBaseOperation::executePixelSampled(float output[4], float x, float y vec[1] = textureSize[1] * (v + textureOffset[1]); vec[2] = textureSize[2] * textureOffset[2]; - retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres, m_pool, m_sceneColorManage); + /* TODO(sergey): Need to pass thread ID to the multitex code, + * then we can avoid having mutex here. + */ + BLI_mutex_lock(&mutex_lock); + retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres, m_pool, m_sceneColorManage, false); + BLI_mutex_unlock(&mutex_lock); if (texres.talpha) output[3] = texres.ta; @@ -120,22 +125,27 @@ void TextureBaseOperation::executePixelSampled(float output[4], float x, float y } } -MemoryBuffer *TextureBaseOperation::createMemoryBuffer(rcti *rect2) +MemoryBuffer *TextureBaseOperation::createMemoryBuffer(rcti * /*rect2*/) { int height = getHeight(); int width = getWidth(); + DataType datatype = this->getOutputSocket()->getDataType(); + int add = 4; + if (datatype == COM_DT_VALUE) { + add = 1; + } rcti rect; rect.xmin = 0; rect.ymin = 0; rect.xmax = width; rect.ymax = height; - MemoryBuffer *result = new MemoryBuffer(NULL, &rect); + MemoryBuffer *result = new MemoryBuffer(datatype, &rect); float *data = result->getBuffer(); for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++, data += 4) { + for (int x = 0; x < width; x++, data += add) { this->executePixelSampled(data, x, y, COM_PS_NEAREST); } } diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cpp b/source/blender/compositor/operations/COM_TonemapOperation.cpp index e8a578fa131..c581d115a2f 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.cpp +++ b/source/blender/compositor/operations/COM_TonemapOperation.cpp @@ -24,6 +24,10 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +extern "C" { +#include "IMB_colormanagement.h" +} + TonemapOperation::TonemapOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); @@ -69,7 +73,7 @@ void PhotoreceptorTonemapOperation::executePixel(float output[4], int x, int y, this->m_imageReader->read(output, x, y, NULL); - const float L = rgb_to_luma_y(output); + const float L = IMB_colormanagement_get_luminance(output); float I_l = output[0] + ic * (L - output[0]); float I_g = avg->cav[0] + ic * (avg->lav - avg->cav[0]); float I_a = I_l + ia * (I_g - I_l); @@ -93,7 +97,7 @@ void TonemapOperation::deinitExecution() NodeOperation::deinitMutex(); } -bool TonemapOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool TonemapOperation::determineDependingAreaOfInterest(rcti * /*input*/, ReadBufferOperation *readOperation, rcti *output) { rcti imageInput; @@ -125,7 +129,7 @@ void *TonemapOperation::initializeTileData(rcti *rect) float Lav = 0.f; float cav[4] = {0.0f, 0.0f, 0.0f, 0.0f}; while (p--) { - float L = rgb_to_luma_y(bc); + float L = IMB_colormanagement_get_luminance(bc); Lav += L; add_v3_v3(cav, bc); lsum += logf(MAX2(L, 0.0f) + 1e-5f); @@ -146,7 +150,7 @@ void *TonemapOperation::initializeTileData(rcti *rect) return this->m_cachedInstance; } -void TonemapOperation::deinitializeTileData(rcti *rect, void *data) +void TonemapOperation::deinitializeTileData(rcti * /*rect*/, void * /*data*/) { /* pass */ } diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp index a76e0866d0d..ca169d03fbc 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp @@ -102,7 +102,9 @@ void TrackPositionOperation::initExecution() } } -void TrackPositionOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void TrackPositionOperation::executePixelSampled(float output[4], + float /*x*/, float /*y*/, + PixelSampler /*sampler*/) { output[0] = this->m_markerPos[this->m_axis] - this->m_relativePos[this->m_axis]; diff --git a/source/blender/compositor/operations/COM_TranslateOperation.cpp b/source/blender/compositor/operations/COM_TranslateOperation.cpp index 191388a42fb..fcf99a10a73 100644 --- a/source/blender/compositor/operations/COM_TranslateOperation.cpp +++ b/source/blender/compositor/operations/COM_TranslateOperation.cpp @@ -52,7 +52,7 @@ void TranslateOperation::deinitExecution() } -void TranslateOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) +void TranslateOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) { ensureDelta(); diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 4b81001fdab..1ec52571be8 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -62,8 +62,7 @@ void VariableSizeBokehBlurOperation::initExecution() #endif QualityStepHelper::initExecution(COM_QH_INCREASE); } -struct VariableSizeBokehBlurTileData -{ +struct VariableSizeBokehBlurTileData { MemoryBuffer *color; MemoryBuffer *bokeh; MemoryBuffer *size; @@ -89,7 +88,7 @@ void *VariableSizeBokehBlurOperation::initializeTileData(rcti *rect) return data; } -void VariableSizeBokehBlurOperation::deinitializeTileData(rcti *rect, void *data) +void VariableSizeBokehBlurOperation::deinitializeTileData(rcti * /*rect*/, void *data) { VariableSizeBokehBlurTileData *result = (VariableSizeBokehBlurTileData *)data; delete result; @@ -137,30 +136,33 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y, copy_v4_fl(multiplier_accum, 1.0f); float size_center = tempSize[0] * scalar; - const int addXStep = QualityStepHelper::getStep() * COM_NUMBER_OF_CHANNELS; - + const int addXStepValue = QualityStepHelper::getStep(); + const int addYStepValue = addXStepValue; + const int addXStepColor = addXStepValue * COM_NUM_CHANNELS_COLOR; + if (size_center > this->m_threshold) { - for (int ny = miny; ny < maxy; ny += QualityStepHelper::getStep()) { + for (int ny = miny; ny < maxy; ny += addYStepValue) { float dy = ny - y; - int offsetNy = ny * inputSizeBuffer->getWidth() * COM_NUMBER_OF_CHANNELS; - int offsetNxNy = offsetNy + (minx * COM_NUMBER_OF_CHANNELS); - for (int nx = minx; nx < maxx; nx += QualityStepHelper::getStep()) { + int offsetValueNy = ny * inputSizeBuffer->getWidth(); + int offsetValueNxNy = offsetValueNy + (minx); + int offsetColorNxNy = offsetValueNxNy * COM_NUM_CHANNELS_COLOR; + for (int nx = minx; nx < maxx; nx += addXStepValue) { if (nx != x || ny != y) { - float size = min(inputSizeFloatBuffer[offsetNxNy] * scalar, size_center); + float size = min(inputSizeFloatBuffer[offsetValueNxNy] * scalar, size_center); if (size > this->m_threshold) { float dx = nx - x; if (size > fabsf(dx) && size > fabsf(dy)) { float uv[2] = { - (float)(COM_BLUR_BOKEH_PIXELS / 2) + (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1), - (float)(COM_BLUR_BOKEH_PIXELS / 2) + (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1)}; - inputBokehBuffer->readNoCheck(bokeh, uv[0], uv[1]); - madd_v4_v4v4(color_accum, bokeh, &inputProgramFloatBuffer[offsetNxNy]); + (float)(COM_BLUR_BOKEH_PIXELS / 2) + (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1), + (float)(COM_BLUR_BOKEH_PIXELS / 2) + (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1)}; + inputBokehBuffer->read(bokeh, uv[0], uv[1]); + madd_v4_v4v4(color_accum, bokeh, &inputProgramFloatBuffer[offsetColorNxNy]); add_v4_v4(multiplier_accum, bokeh); } } } - offsetNxNy += addXStep; - } + offsetColorNxNy += addXStepColor; + offsetValueNxNy += addXStepValue; } } } @@ -184,7 +186,7 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y, void VariableSizeBokehBlurOperation::executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, - list<cl_kernel> *clKernelsToCleanUp) + list<cl_kernel> * /*clKernelsToCleanUp*/) { cl_kernel defocusKernel = device->COM_clCreateKernel("defocusKernel", NULL); @@ -197,8 +199,8 @@ void VariableSizeBokehBlurOperation::executeOpenCL(OpenCLDevice *device, const float max_dim = max(m_width, m_height); cl_float scalar = this->m_do_size_scale ? (max_dim / 100.0f) : 1.0f; - maxBlur = (cl_int)sizeMemoryBuffer->getMaximumValue() * scalar; - maxBlur = min(maxBlur, this->m_maxBlur); + maxBlur = (cl_int)min_ff(sizeMemoryBuffer->getMaximumValue() * scalar, + (float)this->m_maxBlur); device->COM_clAttachMemoryBufferToKernelParameter(defocusKernel, 0, -1, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram); device->COM_clAttachMemoryBufferToKernelParameter(defocusKernel, 1, -1, clMemToCleanUp, inputMemoryBuffers, this->m_inputBokehProgram); diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp index f5890157440..36f06e92436 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp @@ -57,7 +57,7 @@ void VectorBlurOperation::initExecution() void VectorBlurOperation::executePixel(float output[4], int x, int y, void *data) { float *buffer = (float *) data; - int index = (y * this->getWidth() + x) * COM_NUMBER_OF_CHANNELS; + int index = (y * this->getWidth() + x) * COM_NUM_CHANNELS_COLOR; copy_v4_v4(output, &buffer[index]); } @@ -91,7 +91,7 @@ void *VectorBlurOperation::initializeTileData(rcti *rect) return this->m_cachedInstance; } -bool VectorBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool VectorBlurOperation::determineDependingAreaOfInterest(rcti * /*input*/, ReadBufferOperation *readOperation, rcti *output) { if (this->m_cachedInstance == NULL) { rcti newInput; @@ -108,14 +108,12 @@ bool VectorBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBuff void VectorBlurOperation::generateVectorBlur(float *data, MemoryBuffer *inputImage, MemoryBuffer *inputSpeed, MemoryBuffer *inputZ) { - float *zbuf = inputZ->convertToValueBuffer(); NodeBlurData blurdata; blurdata.samples = this->m_settings->samples / QualityStepHelper::getStep(); blurdata.maxspeed = this->m_settings->maxspeed; blurdata.minspeed = this->m_settings->minspeed; blurdata.curved = this->m_settings->curved; blurdata.fac = this->m_settings->fac; - RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), zbuf); - MEM_freeN((void *)zbuf); + RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), inputZ->getBuffer()); return; } diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.cpp b/source/blender/compositor/operations/COM_VectorCurveOperation.cpp index fedc8c6db7d..dfdc54012a8 100644 --- a/source/blender/compositor/operations/COM_VectorCurveOperation.cpp +++ b/source/blender/compositor/operations/COM_VectorCurveOperation.cpp @@ -51,7 +51,6 @@ void VectorCurveOperation::executePixelSampled(float output[4], float x, float y this->m_inputProgram->readSampled(input, x, y, sampler); curvemapping_evaluate_premulRGBF(this->m_curveMapping, output, input); - output[3] = input[3]; } void VectorCurveOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp index 53c0acd781a..aa47d3427d0 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp @@ -23,6 +23,7 @@ #include "COM_ViewerOperation.h" #include "BLI_listbase.h" #include "BKE_image.h" +#include "BKE_scene.h" #include "WM_api.h" #include "WM_types.h" #include "PIL_time.h" @@ -57,6 +58,8 @@ ViewerOperation::ViewerOperation() : NodeOperation() this->m_imageInput = NULL; this->m_alphaInput = NULL; this->m_depthInput = NULL; + this->m_rd = NULL; + this->m_viewName = NULL; } void ViewerOperation::initExecution() @@ -80,7 +83,7 @@ void ViewerOperation::deinitExecution() this->m_outputBuffer = NULL; } -void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber) +void ViewerOperation::executeRegion(rcti *rect, unsigned int /*tileNumber*/) { float *buffer = this->m_outputBuffer; float *depthbuffer = this->m_depthBuffer; @@ -123,11 +126,25 @@ void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber) void ViewerOperation::initImage() { Image *ima = this->m_image; + ImageUser iuser = *this->m_imageUser; void *lock; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, this->m_imageUser, &lock); + ImBuf *ibuf; + + /* make sure the image has the correct number of views */ + if (ima && BKE_scene_multiview_is_render_view_first(this->m_rd, this->m_viewName)) { + BKE_image_verify_viewer_views(this->m_rd, ima, this->m_imageUser); + } - if (!ibuf) return; BLI_lock_thread(LOCK_DRAW_IMAGE); + + /* local changes to the original ImageUser */ + iuser.multi_index = BKE_scene_multiview_view_id_get(this->m_rd, this->m_viewName); + ibuf = BKE_image_acquire_ibuf(ima, &iuser, &lock); + + if (!ibuf) { + BLI_unlock_thread(LOCK_DRAW_IMAGE); + return; + } if (ibuf->x != (int)getWidth() || ibuf->y != (int)getHeight()) { imb_freerectImBuf(ibuf); @@ -146,7 +163,6 @@ void ViewerOperation::initImage() if (m_doDepthBuffer) { addzbuffloatImBuf(ibuf); } - BLI_unlock_thread(LOCK_DRAW_IMAGE); /* now we combine the input with ibuf */ this->m_outputBuffer = ibuf->rect_float; @@ -159,6 +175,8 @@ void ViewerOperation::initImage() } BKE_image_release_ibuf(this->m_image, this->m_ibuf, lock); + + BLI_unlock_thread(LOCK_DRAW_IMAGE); } void ViewerOperation::updateImage(rcti *rect) diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h index dcc7ffa3730..107aee3a82f 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.h +++ b/source/blender/compositor/operations/COM_ViewerOperation.h @@ -40,7 +40,9 @@ private: bool m_doDepthBuffer; ImBuf *m_ibuf; bool m_useAlphaInput; - + const RenderData *m_rd; + const char *m_viewName; + const ColorManagedViewSettings *m_viewSettings; const ColorManagedDisplaySettings *m_displaySettings; @@ -53,7 +55,7 @@ public: void initExecution(); void deinitExecution(); void executeRegion(rcti *rect, unsigned int tileNumber); - bool isOutputOperation(bool rendering) const { if (G.background) return false; return isActiveViewerOutput(); } + bool isOutputOperation(bool /*rendering*/) const { if (G.background) return false; return isActiveViewerOutput(); } void setImage(Image *image) { this->m_image = image; } void setImageUser(ImageUser *imageUser) { this->m_imageUser = imageUser; } const bool isActiveViewerOutput() const { return this->m_active; } @@ -67,6 +69,8 @@ public: const CompositorPriority getRenderPriority() const; bool isViewerOperation() const { return true; } void setUseAlphaInput(bool value) { this->m_useAlphaInput = value; } + void setRenderData(const RenderData *rd) { this->m_rd = rd; } + void setViewName(const char *viewName) { this->m_viewName = viewName; } void setViewSettings(const ColorManagedViewSettings *viewSettings) { this->m_viewSettings = viewSettings; } void setDisplaySettings(const ColorManagedDisplaySettings *displaySettings) { this->m_displaySettings = displaySettings; } diff --git a/source/blender/compositor/operations/COM_WrapOperation.cpp b/source/blender/compositor/operations/COM_WrapOperation.cpp index c30361d1df8..7fbef453a13 100644 --- a/source/blender/compositor/operations/COM_WrapOperation.cpp +++ b/source/blender/compositor/operations/COM_WrapOperation.cpp @@ -23,7 +23,7 @@ #include "COM_WrapOperation.h" -WrapOperation::WrapOperation() : ReadBufferOperation() +WrapOperation::WrapOperation(DataType datatype) : ReadBufferOperation(datatype) { this->m_wrappingType = CMP_NODE_WRAP_NONE; } diff --git a/source/blender/compositor/operations/COM_WrapOperation.h b/source/blender/compositor/operations/COM_WrapOperation.h index 33ea1280564..92c93565691 100644 --- a/source/blender/compositor/operations/COM_WrapOperation.h +++ b/source/blender/compositor/operations/COM_WrapOperation.h @@ -29,7 +29,7 @@ class WrapOperation : public ReadBufferOperation { private: int m_wrappingType; public: - WrapOperation(); + WrapOperation(DataType datetype); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp index 832864b399d..b3c1c00804e 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -25,10 +25,10 @@ #include <stdio.h> #include "COM_OpenCLDevice.h" -WriteBufferOperation::WriteBufferOperation() : NodeOperation() +WriteBufferOperation::WriteBufferOperation(DataType datatype) : NodeOperation() { - this->addInputSocket(COM_DT_COLOR); - this->m_memoryProxy = new MemoryProxy(); + this->addInputSocket(datatype); + this->m_memoryProxy = new MemoryProxy(datatype); this->m_memoryProxy->setWriteBufferOperation(this); this->m_memoryProxy->setExecutor(NULL); } @@ -57,10 +57,11 @@ void WriteBufferOperation::deinitExecution() this->m_memoryProxy->free(); } -void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber) +void WriteBufferOperation::executeRegion(rcti *rect, unsigned int /*tileNumber*/) { MemoryBuffer *memoryBuffer = this->m_memoryProxy->getBuffer(); float *buffer = memoryBuffer->getBuffer(); + const int num_channels = memoryBuffer->get_num_channels(); if (this->m_input->isComplex()) { void *data = this->m_input->initializeTileData(rect); int x1 = rect->xmin; @@ -71,10 +72,10 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber) int y; bool breaked = false; for (y = y1; y < y2 && (!breaked); y++) { - int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS; + int offset4 = (y * memoryBuffer->getWidth() + x1) * num_channels; for (x = x1; x < x2; x++) { this->m_input->read(&(buffer[offset4]), x, y, data); - offset4 += COM_NUMBER_OF_CHANNELS; + offset4 += num_channels; } if (isBreaked()) { breaked = true; @@ -96,10 +97,10 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber) int y; bool breaked = false; for (y = y1; y < y2 && (!breaked); y++) { - int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS; + int offset4 = (y * memoryBuffer->getWidth() + x1) * num_channels; for (x = x1; x < x2; x++) { this->m_input->readSampled(&(buffer[offset4]), x, y, COM_PS_NEAREST); - offset4 += COM_NUMBER_OF_CHANNELS; + offset4 += num_channels; } if (isBreaked()) { breaked = true; @@ -109,7 +110,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber) memoryBuffer->setCreatedState(); } -void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti *rect, unsigned int chunkNumber, +void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti * /*rect*/, unsigned int /*chunkNumber*/, MemoryBuffer **inputMemoryBuffers, MemoryBuffer *outputBuffer) { float *outputFloatBuffer = outputBuffer->getBuffer(); @@ -126,12 +127,9 @@ void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti *rect, const unsigned int outputBufferWidth = outputBuffer->getWidth(); const unsigned int outputBufferHeight = outputBuffer->getHeight(); - const cl_image_format imageFormat = { - CL_RGBA, - CL_FLOAT - }; + const cl_image_format *imageFormat = device->determineImageFormat(outputBuffer); - cl_mem clOutputBuffer = clCreateImage2D(device->getContext(), CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, &imageFormat, outputBufferWidth, outputBufferHeight, 0, outputFloatBuffer, &error); + cl_mem clOutputBuffer = clCreateImage2D(device->getContext(), CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, imageFormat, outputBufferWidth, outputBufferHeight, 0, outputFloatBuffer, &error); if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } // STEP 2 diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h index 96466df979c..9220cb179c6 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.h +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h @@ -35,7 +35,7 @@ class WriteBufferOperation : public NodeOperation { bool m_single_value; /* single value stored in buffer */ NodeOperation *m_input; public: - WriteBufferOperation(); + WriteBufferOperation(DataType datatype); ~WriteBufferOperation(); MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; } void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); |