diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2015-09-24 18:24:20 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2015-09-24 18:24:20 +0300 |
commit | 27b3ea622f8bd313a8e2827dfec752bf2125566c (patch) | |
tree | f212e49d224ce8e1cfc3b17a64ae524711494391 /source/blender/compositor/operations | |
parent | 372dff8d1dc7e24d4b2cd37de245588ecfce8bfa (diff) | |
parent | de80e687689032cb85179a1f7e89750573631d5d (diff) |
Merge remote-tracking branch 'origin/master' into cycles_camera_nodescycles_camera_nodes
Note: the branch currently crashes in blender_camera_nodes.cpp:
BL::NodeTree b_ntree = b_data.node_groups[nodes_tree_name];
The crash was introduced in:
cb7cf523e5c000609f32a382e2c0fcc57f635a42
Conflicts:
intern/cycles/SConscript
intern/cycles/blender/addon/__init__.py
intern/cycles/blender/addon/properties.py
intern/cycles/blender/blender_camera.cpp
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/svm/svm.h
intern/cycles/kernel/svm/svm_types.h
intern/cycles/render/camera.cpp
intern/cycles/render/camera.h
Diffstat (limited to 'source/blender/compositor/operations')
97 files changed, 1450 insertions, 591 deletions
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); |