1
1

Compare commits

...

5 Commits

Author SHA1 Message Date
5fcc889baa Merge branch 'blender-tiles' of gitorious.org:blender-tiles/blender-tiles into blender-tiles
Conflicts:
	source/blender/blenlib/BLI_compiler_compat.h
	source/blender/compositor/CMakeLists.txt
	source/blender/compositor/intern/COM_ChannelInfo.h
	source/blender/compositor/intern/COM_ExecutionSystem.cpp
	source/blender/compositor/intern/COM_MemoryBuffer.cpp
	source/blender/compositor/intern/COM_OpenCLDevice.cpp
	source/blender/compositor/nodes/COM_SocketProxyNode.cpp
	source/blender/compositor/operations/COM_CompositorOperation.cpp
	source/blender/compositor/operations/COM_ReadBufferOperation.h
	source/blender/compositor/operations/COM_RenderLayersProg.cpp
2014-05-12 21:45:43 +02:00
3b691b54b1 Initialize colors, vectors and values in RenderLayersProg 2014-05-12 20:25:30 +02:00
948703b36d Tiles: synced with master 2014-05-12 20:22:40 +02:00
815c999382 Initialize colors, vectors and values in RenderLayersProg 2014-05-12 18:21:45 +02:00
0563280bff Compositor squashed patch reapplied
Started with the MemoryBufferValue
still a lot needs to be done
stopped at testing the dilate/erode

TILES: did some fixed for value buffer

Determine image format of OpenCL device

TILES: TextureNode fix

TILES: moved buffer sizes to constants for easy access.

TILES: fixed some nodes.
still working on the defocus node

TILES: fixed glare, keying, defocus, normalize, vector curves
2014-04-25 16:32:09 +02:00
53 changed files with 1391 additions and 685 deletions

View File

@@ -74,6 +74,12 @@ set(SRC
intern/COM_MemoryProxy.h intern/COM_MemoryProxy.h
intern/COM_MemoryBuffer.cpp intern/COM_MemoryBuffer.cpp
intern/COM_MemoryBuffer.h intern/COM_MemoryBuffer.h
intern/COM_MemoryBufferColor.cpp
intern/COM_MemoryBufferColor.h
intern/COM_MemoryBufferVector.cpp
intern/COM_MemoryBufferVector.h
intern/COM_MemoryBufferValue.cpp
intern/COM_MemoryBufferValue.h
intern/COM_WorkScheduler.cpp intern/COM_WorkScheduler.cpp
intern/COM_WorkScheduler.h intern/COM_WorkScheduler.h
intern/COM_WorkPackage.cpp intern/COM_WorkPackage.cpp
@@ -90,8 +96,6 @@ set(SRC
intern/COM_OpenCLDevice.h intern/COM_OpenCLDevice.h
intern/COM_CompositorContext.cpp intern/COM_CompositorContext.cpp
intern/COM_CompositorContext.h intern/COM_CompositorContext.h
intern/COM_ChannelInfo.cpp
intern/COM_ChannelInfo.h
intern/COM_SingleThreadedOperation.cpp intern/COM_SingleThreadedOperation.cpp
intern/COM_SingleThreadedOperation.h intern/COM_SingleThreadedOperation.h
intern/COM_Debug.cpp intern/COM_Debug.cpp

View File

@@ -105,7 +105,9 @@ typedef enum OrderOfChunks {
#define COM_RULE_OF_THIRDS_DIVIDER 100.0f #define COM_RULE_OF_THIRDS_DIVIDER 100.0f
#define COM_NUMBER_OF_CHANNELS 4 #define COM_NO_CHANNELS_VALUE 1
#define COM_NO_CHANNELS_VECTOR 3
#define COM_NO_CHANNELS_COLOR 4
#define COM_BLUR_BOKEH_PIXELS 512 #define COM_BLUR_BOKEH_PIXELS 512

View File

@@ -1,35 +0,0 @@
/*
* Copyright 2011, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ChannelInfo.h"
#include "COM_defines.h"
#include <stdio.h>
/**
* @brief create new ChannelInfo instance and sets the defaults.
*/
ChannelInfo::ChannelInfo()
{
this->m_number = 0;
this->m_premultiplied = true;
this->m_type = COM_CT_UNUSED;
}

View File

@@ -1,121 +0,0 @@
/*
* Copyright 2011, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_ChannelInfo_h
#define _COM_ChannelInfo_h
#include <vector>
#include "BKE_text.h"
#include <string>
#include "DNA_node_types.h"
#include "BLI_rect.h"
using namespace std;
/**
* @brief List of possible channel types
* @ingroup Model
*/
typedef enum ChannelType {
COM_CT_ColorComponent /** @brief this channel is contains color information. Specific used is determined by channelnumber, and in the future color space */,
COM_CT_Alpha /** @brief this channel is contains transparency value */,
COM_CT_Value /** @brief this channel is contains a value */,
COM_CT_X /** @brief this channel is contains a X value */,
COM_CT_Y /** @brief this channel is contains a Y value */,
COM_CT_Z /** @brief this channel is contains a Z value */,
COM_CT_W /** @brief this channel is contains a W value */,
COM_CT_UNUSED /** @brief this channel is unused */
} ChannelType;
/**
* @brief ChannelInfo holds information about a channel.
*
* Channels are transported from node to node via a NodeLink.
* ChannelInfo holds specific setting of these channels in order that the to-node of the link
* Can handle specific logic per channel setting.
*
* @note currently this is not used, but a future place to implement color spacing and other things.
* @ingroup Model
*/
class ChannelInfo {
private:
/**
* @brief the channel number, in the link. [0-3]
*/
int m_number;
/**
* @brief type of channel
*/
ChannelType m_type;
/**
* @brieg Is this value in this channel premultiplied with its alpha
* @note only valid if type = ColorComponent;
*/
bool m_premultiplied;
// /**
// * Color space of this value.
// * only valid when type = ColorComponent;
// */
// string colorspacename;
public:
/**
* @brief creates a new ChannelInfo and set default values
*/
ChannelInfo();
/**
* @brief set the index of this channel in the NodeLink
*/
void setNumber(const int number) { this->m_number = number; }
/**
* @brief get the index of this channel in the NodeLink
*/
const int getNumber() const { return this->m_number; }
/**
* @brief set the type of channel
*/
void setType(const ChannelType type) { this->m_type = type; }
/**
* @brief get the type of channel
*/
const ChannelType getType() const { return this->m_type; }
/**
* @brief set the premultiplicatioin of this channel
*/
void setPremultiplied(const bool premultiplied) { this->m_premultiplied = premultiplied; }
/**
* @brief is this channel premultiplied
*/
const bool isPremultiplied() const { return this->m_premultiplied; }
};
#endif

View File

@@ -372,7 +372,7 @@ MemoryBuffer **ExecutionGroup::getInputBuffersOpenCL(int chunkNumber)
MemoryBuffer *ExecutionGroup::constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy, rcti *rect) MemoryBuffer *ExecutionGroup::constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy, rcti *rect)
{ {
MemoryBuffer *imageBuffer = memoryProxy->getBuffer(); MemoryBuffer *imageBuffer = memoryProxy->getBuffer();
MemoryBuffer *result = new MemoryBuffer(memoryProxy, rect); MemoryBuffer *result = MemoryBuffer::create(memoryProxy, rect);
result->copyContentFrom(imageBuffer); result->copyContentFrom(imageBuffer);
return result; return result;
} }
@@ -465,7 +465,7 @@ MemoryBuffer *ExecutionGroup::allocateOutputBuffer(int chunkNumber, rcti *rect)
NodeOperation *operation = this->getOutputOperation(); NodeOperation *operation = this->getOutputOperation();
if (operation->isWriteBufferOperation()) { if (operation->isWriteBufferOperation()) {
WriteBufferOperation *writeOperation = (WriteBufferOperation *)operation; WriteBufferOperation *writeOperation = (WriteBufferOperation *)operation;
MemoryBuffer *buffer = new MemoryBuffer(writeOperation->getMemoryProxy(), rect); MemoryBuffer *buffer = MemoryBuffer::create(writeOperation->getMemoryProxy(), rect);
return buffer; return buffer;
} }
return NULL; return NULL;

View File

@@ -98,7 +98,7 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editin
} }
} }
// DebugInfo::graphviz(this); DebugInfo::graphviz(this);
} }
ExecutionSystem::~ExecutionSystem() ExecutionSystem::~ExecutionSystem()

View File

@@ -27,7 +27,11 @@
using std::min; using std::min;
using std::max; using std::max;
unsigned int MemoryBuffer::determineBufferSize() #include "COM_MemoryBufferColor.h"
#include "COM_MemoryBufferVector.h"
#include "COM_MemoryBufferValue.h"
unsigned int MemoryBuffer::determineBufferSize() const
{ {
return getWidth() * getHeight(); return getWidth() * getHeight();
} }
@@ -41,38 +45,109 @@ int MemoryBuffer::getHeight() const
return this->m_rect.ymax - this->m_rect.ymin; return this->m_rect.ymax - this->m_rect.ymin;
} }
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect) MemoryBuffer* MemoryBuffer::create(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect) {
DataType type;
type = memoryProxy->getDataType();
if (type == COM_DT_VALUE) {
return new MemoryBufferValue(memoryProxy, chunkNumber, rect);
}
else if (type == COM_DT_VECTOR) {
return new MemoryBufferVector(memoryProxy, chunkNumber, rect);
}
else {
return new MemoryBufferColor(memoryProxy, chunkNumber, rect);
}
}
MemoryBuffer* MemoryBuffer::create(MemoryProxy *memoryProxy, rcti *rect) {
DataType type;
type = memoryProxy->getDataType();
if (type==COM_DT_VALUE){
return new MemoryBufferValue(memoryProxy, rect);
}
else if (type == COM_DT_VECTOR) {
return new MemoryBufferVector(memoryProxy, rect);
}
else {
return new MemoryBufferColor(memoryProxy, rect);
}
}
MemoryBuffer* MemoryBuffer::create(DataType datatype, rcti *rect) {
if (datatype==COM_DT_VALUE){
return new MemoryBufferValue(datatype, rect);
}
else if (datatype == COM_DT_VECTOR) {
return new MemoryBufferVector(datatype, rect);
}
else {
return new MemoryBufferColor(datatype, rect);
}
}
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect, unsigned int no_channels)
{ {
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax); BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
this->m_memoryProxy = memoryProxy; this->m_memoryProxy = memoryProxy;
this->m_chunkNumber = chunkNumber; this->m_chunkNumber = chunkNumber;
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, "COM_MemoryBuffer"); this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * no_channels, "COM_MemoryBuffer");
this->m_state = COM_MB_ALLOCATED; this->m_state = COM_MB_ALLOCATED;
this->m_datatype = COM_DT_COLOR;
this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin; this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin;
this->m_no_channels = no_channels;
} }
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect) MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect, unsigned int no_channels)
{ {
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax); BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
this->m_memoryProxy = memoryProxy; this->m_memoryProxy = memoryProxy;
this->m_chunkNumber = -1; this->m_chunkNumber = -1;
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, "COM_MemoryBuffer"); this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * no_channels, "COM_MemoryBuffer");
this->m_state = COM_MB_TEMPORARILY; this->m_state = COM_MB_TEMPORARILY;
this->m_datatype = COM_DT_COLOR;
this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin; this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin;
} this->m_no_channels = no_channels;
MemoryBuffer *MemoryBuffer::duplicate()
{
MemoryBuffer *result = new MemoryBuffer(this->m_memoryProxy, &this->m_rect);
memcpy(result->m_buffer, this->m_buffer, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float));
return result;
}
void MemoryBuffer::clear()
{
memset(this->m_buffer, 0, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float));
} }
MemoryBuffer::MemoryBuffer(DataType datatype, rcti *rect, unsigned int no_channels) {
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
this->m_memoryProxy = NULL;
this->m_chunkNumber = -1;
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * no_channels, "COM_MemoryBuffer");
this->m_state = COM_MB_TEMPORARILY;
this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin;
this->m_no_channels = no_channels;
}
void MemoryBuffer::clear()
{
memset(this->m_buffer, 0, this->determineBufferSize() * this->m_no_channels * sizeof(float));
}
void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer)
{
if (!otherBuffer) {
BLI_assert(0);
return;
}
unsigned int otherY;
unsigned int minX = max(this->m_rect.xmin, otherBuffer->m_rect.xmin);
unsigned int maxX = min(this->m_rect.xmax, otherBuffer->m_rect.xmax);
unsigned int minY = max(this->m_rect.ymin, otherBuffer->m_rect.ymin);
unsigned int maxY = min(this->m_rect.ymax, otherBuffer->m_rect.ymax);
int offset;
int otherOffset;
for (otherY = minY; otherY < maxY; otherY++) {
otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_chunkWidth + minX - otherBuffer->m_rect.xmin) * this->m_no_channels;
offset = ((otherY - this->m_rect.ymin) * this->m_chunkWidth + minX - this->m_rect.xmin) * this->m_no_channels;
memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * this->m_no_channels * sizeof(float));
}
}
// TODO: this method needs to be checked! At Mind 2014
float *MemoryBuffer::convertToValueBuffer() float *MemoryBuffer::convertToValueBuffer()
{ {
const unsigned int size = this->determineBufferSize(); const unsigned int size = this->determineBufferSize();
@@ -83,29 +158,16 @@ float *MemoryBuffer::convertToValueBuffer()
const float *fp_src = this->m_buffer; const float *fp_src = this->m_buffer;
float *fp_dst = result; float *fp_dst = result;
for (i = 0; i < size; i++, fp_dst++, fp_src += COM_NUMBER_OF_CHANNELS) { for (i = 0; i < size; i++, fp_dst++, fp_src += COM_NO_CHANNELS_COLOR) {
*fp_dst = *fp_src; *fp_dst = *fp_src;
} }
return result; return result;
} }
float MemoryBuffer::getMaximumValue() float MemoryBuffer::getMaximumValue() const
{ {
float result = this->m_buffer[0]; return 0.0f;
const unsigned int size = this->determineBufferSize();
unsigned int i;
const float *fp_src = this->m_buffer;
for (i = 0; i < size; i++, fp_src += COM_NUMBER_OF_CHANNELS) {
float value = *fp_src;
if (value > result) {
result = value;
}
}
return result;
} }
float MemoryBuffer::getMaximumValue(rcti *rect) float MemoryBuffer::getMaximumValue(rcti *rect)
@@ -116,7 +178,7 @@ float MemoryBuffer::getMaximumValue(rcti *rect)
BLI_rcti_isect(rect, &this->m_rect, &rect_clamp); BLI_rcti_isect(rect, &this->m_rect, &rect_clamp);
if (!BLI_rcti_is_empty(&rect_clamp)) { if (!BLI_rcti_is_empty(&rect_clamp)) {
MemoryBuffer *temp = new MemoryBuffer(NULL, &rect_clamp); MemoryBuffer *temp = MemoryBuffer::create(COM_DT_VALUE, &rect_clamp);
temp->copyContentFrom(this); temp->copyContentFrom(this);
float result = temp->getMaximumValue(); float result = temp->getMaximumValue();
delete temp; delete temp;
@@ -136,204 +198,6 @@ MemoryBuffer::~MemoryBuffer()
} }
} }
void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer) const int MemoryBuffer::get_no_channels() const {
{ return this->m_no_channels;
if (!otherBuffer) {
BLI_assert(0);
return;
}
unsigned int otherY;
unsigned int minX = max(this->m_rect.xmin, otherBuffer->m_rect.xmin);
unsigned int maxX = min(this->m_rect.xmax, otherBuffer->m_rect.xmax);
unsigned int minY = max(this->m_rect.ymin, otherBuffer->m_rect.ymin);
unsigned int maxY = min(this->m_rect.ymax, otherBuffer->m_rect.ymax);
int offset;
int otherOffset;
for (otherY = minY; otherY < maxY; otherY++) {
otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_chunkWidth + minX - otherBuffer->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
offset = ((otherY - this->m_rect.ymin) * this->m_chunkWidth + minX - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * COM_NUMBER_OF_CHANNELS * sizeof(float));
}
}
void MemoryBuffer::writePixel(int x, int y, const float color[4])
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
y >= this->m_rect.ymin && y < this->m_rect.ymax)
{
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
copy_v4_v4(&this->m_buffer[offset], color);
}
}
void MemoryBuffer::addPixel(int x, int y, const float color[4])
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
y >= this->m_rect.ymin && y < this->m_rect.ymax)
{
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
add_v4_v4(&this->m_buffer[offset], color);
}
}
// table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2
// used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible
#define EWA_MAXIDX 255
static const float EWA_WTS[EWA_MAXIDX + 1] = {
1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f,
0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f,
0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f,
0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f,
0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f,
0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f,
0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f,
0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f,
0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f,
0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f,
0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f,
0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f,
0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f,
0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f,
0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f,
0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f,
0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f,
0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f,
0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f,
0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f,
0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f,
0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f,
0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f,
0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f,
0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f,
0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f,
0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f,
0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f,
0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f,
0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f,
0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f,
0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f
};
static void ellipse_bounds(float A, float B, float C, float F, float &xmax, float &ymax)
{
float denom = 4.0f * A * C - B * B;
if (denom > 0.0f && A != 0.0f && C != 0.0f) {
xmax = sqrtf(F) / (2.0f * A) * (sqrtf(F * (4.0f * A - B * B / C)) + B * B * sqrtf(F / (C * denom)));
ymax = sqrtf(F) / (2.0f * C) * (sqrtf(F * (4.0f * C - B * B / A)) + B * B * sqrtf(F / (A * denom)));
}
else {
xmax = 0.0f;
ymax = 0.0f;
}
}
static void ellipse_params(float Ux, float Uy, float Vx, float Vy,
float &A, float &B, float &C, float &F, float &umax, float &vmax)
{
A = Vx * Vx + Vy * Vy;
B = -2.0f * (Ux * Vx + Uy * Vy);
C = Ux * Ux + Uy * Uy;
F = A * C - B * B * 0.25f;
float factor = (F != 0.0f ? (float)(EWA_MAXIDX + 1) / F : 0.0f);
A *= factor;
B *= factor;
C *= factor;
F = (float)(EWA_MAXIDX + 1);
ellipse_bounds(A, B, C, sqrtf(F), umax, vmax);
}
/**
* Filtering method based on
* "Creating raster omnimax images from multiple perspective views using the elliptical weighted average filter"
* by Ned Greene and Paul S. Heckbert (1986)
*/
void MemoryBuffer::readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler)
{
zero_v4(result);
int width = this->getWidth(), height = this->getHeight();
if (width == 0 || height == 0)
return;
float u = uv[0], v = uv[1];
float Ux = derivatives[0][0], Vx = derivatives[1][0], Uy = derivatives[0][1], Vy = derivatives[1][1];
float A, B, C, F, ue, ve;
ellipse_params(Ux, Uy, Vx, Vy, A, B, C, F, ue, ve);
/* Note: highly eccentric ellipses can lead to large texture space areas to filter!
* This is limited somewhat by the EWA_WTS size in the loop, but a nicer approach
* could be the one found in
* "High Quality Elliptical Texture Filtering on GPU"
* by Pavlos Mavridis and Georgios Papaioannou
* in which the eccentricity of the ellipse is clamped.
*/
int U0 = (int)u;
int V0 = (int)v;
/* pixel offset for interpolation */
float ufac = u - floorf(u), vfac = v - floorf(v);
/* filter size */
int u1 = (int)(u - ue);
int u2 = (int)(u + ue);
int v1 = (int)(v - ve);
int v2 = (int)(v + ve);
/* sane clamping to avoid unnecessarily huge loops */
/* note: if eccentricity gets clamped (see above),
* the ue/ve limits can also be lowered accordingly
*/
if (U0 - u1 > EWA_MAXIDX) u1 = U0 - EWA_MAXIDX;
if (u2 - U0 > EWA_MAXIDX) u2 = U0 + EWA_MAXIDX;
if (V0 - v1 > EWA_MAXIDX) v1 = V0 - EWA_MAXIDX;
if (v2 - V0 > EWA_MAXIDX) v2 = V0 + EWA_MAXIDX;
/* Early output check for cases the whole region is outside of the buffer. */
if ((u2 < m_rect.xmin || u1 >= m_rect.xmax) ||
(v2 < m_rect.ymin || v1 >= m_rect.ymax))
{
zero_v4(result);
return;
}
/* Clamp sampling rectagle to the buffer dimensions. */
u1 = max_ii(u1, m_rect.xmin);
u2 = min_ii(u2, m_rect.xmax);
v1 = max_ii(v1, m_rect.ymin);
v2 = min_ii(v2, m_rect.ymax);
float DDQ = 2.0f * A;
float U = u1 - U0;
float ac1 = A * (2.0f * U + 1.0f);
float ac2 = A * U * U;
float BU = B * U;
float sum = 0.0f;
for (int v = v1; v <= v2; ++v) {
float V = v - V0;
float DQ = ac1 + B * V;
float Q = (C * V + BU) * V + ac2;
for (int u = u1; u <= u2; ++u) {
if (Q < F) {
float tc[4];
const float wt = EWA_WTS[CLAMPIS((int)Q, 0, EWA_MAXIDX)];
switch (sampler) {
case COM_PS_NEAREST: read(tc, u, v); break;
case COM_PS_BILINEAR: readBilinear(tc, (float)u + ufac, (float)v + vfac); break;
case COM_PS_BICUBIC: readBilinear(tc, (float)u + ufac, (float)v + vfac); break; /* XXX no readBicubic method yet */
default: zero_v4(tc); break;
}
madd_v4_v4fl(result, tc, wt);
sum += wt;
}
Q += DQ;
DQ += DDQ;
}
}
mul_v4_fl(result, (sum != 0.0f ? 1.0f / sum : 0.0f));
} }

View File

@@ -61,57 +61,84 @@ class MemoryProxy;
class MemoryBuffer { class MemoryBuffer {
private: private:
/** /**
* @brief proxy of the memory (same for all chunks in the same buffer) * brief refers to the chunknumber within the executiongroup where related to the MemoryProxy
* @see memoryProxy
*/ */
MemoryProxy *m_memoryProxy; unsigned int m_chunkNumber;
/** /**
* @brief the type of buffer COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR * @brief state of the buffer
*/ */
DataType m_datatype; MemoryBufferState m_state;
/**
* @brief the number of channels that form a single pixel in this buffer
*/
unsigned int m_no_channels;
protected:
/**
* @brief width of the chunk
*/
unsigned int m_chunkWidth;
/** /**
* @brief region of this buffer inside relative to the MemoryProxy * @brief region of this buffer inside relative to the MemoryProxy
*/ */
rcti m_rect; rcti m_rect;
/** /**
* brief refers to the chunknumber within the executiongroup where related to the MemoryProxy * @brief proxy of the memory (same for all chunks in the same buffer)
* @see memoryProxy
*/ */
unsigned int m_chunkNumber; MemoryProxy *m_memoryProxy;
/**
* @brief width of the chunk
*/
unsigned int m_chunkWidth;
/**
* @brief state of the buffer
*/
MemoryBufferState m_state;
/** /**
* @brief the actual float buffer/data * @brief the actual float buffer/data
*/ */
float *m_buffer; float *m_buffer;
public:
/** /**
* @brief construct new MemoryBuffer for a chunk * @brief construct new MemoryBuffer for a chunk
*
* @param no_channels Number of channels that must be allocated for every pixel
*/ */
MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect); MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect, unsigned int no_channels);
/** /**
* @brief construct new temporarily MemoryBuffer for an area * @brief construct new temporarily MemoryBuffer for an area
*
* @param no_channels Number of channels that must be allocated for every pixel
*/ */
MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect); MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect, unsigned int no_channels);
/**
* @brief construct new temporarily MemoryBuffer for an area
*
* @param no_channels Number of channels that must be allocated for every pixel
*/
MemoryBuffer(DataType datatype, rcti *rect, unsigned int no_channels);
public:
/** /**
* @brief factory method for the constructor, selecting the right subclass
*/
static MemoryBuffer* create(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
/**
* @brief factory method for the constructor, selecting the right subclass, creating a temporarily buffer
*/
static MemoryBuffer* create(MemoryProxy *memoryProxy, rcti *rect);
/**
* @brief factory method for the constructor, selecting the right subclass, creating a temporarily buffer
*/
static MemoryBuffer* create(DataType datatype, rcti *rect);
/**
* @brief destructor * @brief destructor
*/ */
~MemoryBuffer(); virtual ~MemoryBuffer();
/** /**
* @brief read the ChunkNumber of this MemoryBuffer * @brief read the ChunkNumber of this MemoryBuffer
@@ -164,89 +191,24 @@ public:
} }
} }
inline void read(float result[4], int x, int y, virtual void read(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP, MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP) MemoryBufferExtend extend_y = COM_MB_CLIP) = 0;
{
bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
if (clip_x || clip_y) {
/* clip result outside rect is zero */
zero_v4(result);
}
else {
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS;
copy_v4_v4(result, &this->m_buffer[offset]);
}
}
inline void readNoCheck(float result[4], int x, int y,
virtual void readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP, MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP) MemoryBufferExtend extend_y = COM_MB_CLIP) = 0;
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS;
BLI_assert(offset >= 0);
BLI_assert(offset < this->determineBufferSize() * COM_NUMBER_OF_CHANNELS); virtual void writePixel(int x, int y, const float *color) = 0;
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) && virtual void addPixel(int x, int y, const float *color) = 0;
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax))); virtual void readBilinear(float *result, float x, float y,
#if 0
/* always true */
BLI_assert((int)(MEM_allocN_len(this->m_buffer) / sizeof(*this->m_buffer)) ==
(int)(this->determineBufferSize() * COM_NUMBER_OF_CHANNELS));
#endif
copy_v4_v4(result, &this->m_buffer[offset]);
}
void writePixel(int x, int y, const float color[4]);
void addPixel(int x, int y, const float color[4]);
inline void readBilinear(float result[4], float x, float y,
MemoryBufferExtend extend_x = COM_MB_CLIP, MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP) MemoryBufferExtend extend_y = COM_MB_CLIP) = 0;
{
int x1 = floor(x);
int y1 = floor(y);
int x2 = x1 + 1;
int y2 = y1 + 1;
wrap_pixel(x1, y1, extend_x, extend_y);
wrap_pixel(x2, y2, extend_x, extend_y);
float valuex = x - x1;
float valuey = y - y1;
float mvaluex = 1.0f - valuex;
float mvaluey = 1.0f - valuey;
float color1[4]; virtual void readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler) {}
float color2[4];
float color3[4];
float color4[4];
read(color1, x1, y1);
read(color2, x1, y2);
read(color3, x2, y1);
read(color4, x2, y2);
color1[0] = color1[0] * mvaluey + color2[0] * valuey;
color1[1] = color1[1] * mvaluey + color2[1] * valuey;
color1[2] = color1[2] * mvaluey + color2[2] * valuey;
color1[3] = color1[3] * mvaluey + color2[3] * valuey;
color3[0] = color3[0] * mvaluey + color4[0] * valuey;
color3[1] = color3[1] * mvaluey + color4[1] * valuey;
color3[2] = color3[2] * mvaluey + color4[2] * valuey;
color3[3] = color3[3] * mvaluey + color4[3] * valuey;
result[0] = color1[0] * mvaluex + color3[0] * valuex;
result[1] = color1[1] * mvaluex + color3[1] * valuex;
result[2] = color1[2] * mvaluex + color3[2] * valuex;
result[3] = color1[3] * mvaluex + color3[3] * valuex;
}
void readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler);
/** /**
* @brief is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk) * @brief is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk)
@@ -282,13 +244,23 @@ public:
*/ */
void clear(); void clear();
MemoryBuffer *duplicate(); virtual MemoryBuffer *duplicate() = 0;
float *convertToValueBuffer(); float *convertToValueBuffer();
float getMaximumValue(); virtual float getMaximumValue() const;
float getMaximumValue(rcti *rect); float getMaximumValue(rcti *rect);
private:
unsigned int determineBufferSize(); /**
* @brief return the number of channels that form a single pixel.
*
* Value = 1
* Vector= 3
* Color = 4
*/
const int get_no_channels() const;
protected:
unsigned int determineBufferSize() const;
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBuffer") MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBuffer")

View File

@@ -0,0 +1,291 @@
/*
* Copyright 2014, 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
*/
#include "COM_MemoryBufferColor.h"
#define NUMBER_OF_CHANNELS COM_NO_CHANNELS_COLOR
MemoryBufferColor::MemoryBufferColor(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect):
MemoryBuffer(memoryProxy, chunkNumber, rect, NUMBER_OF_CHANNELS)
{
}
MemoryBufferColor::MemoryBufferColor(MemoryProxy *memoryProxy, rcti *rect) :
MemoryBuffer(memoryProxy, rect, NUMBER_OF_CHANNELS)
{
}
MemoryBufferColor::MemoryBufferColor(DataType datatype, rcti *rect) :
MemoryBuffer(datatype, rect, NUMBER_OF_CHANNELS) {
}
MemoryBuffer *MemoryBufferColor::duplicate()
{
MemoryBufferColor *result = new MemoryBufferColor(this->m_memoryProxy, &this->m_rect);
memcpy(result->getBuffer(), this->getBuffer(), this->determineBufferSize() * NUMBER_OF_CHANNELS * sizeof(float));
return result;
}
// --- write pixels ---
void MemoryBufferColor::writePixel(int x, int y, const float *color)
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
y >= this->m_rect.ymin && y < this->m_rect.ymax)
{
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * NUMBER_OF_CHANNELS;
copy_v4_v4(&this->m_buffer[offset], color);
}
}
void MemoryBufferColor::addPixel(int x, int y, const float *color)
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
y >= this->m_rect.ymin && y < this->m_rect.ymax)
{
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * NUMBER_OF_CHANNELS;
add_v4_v4(&this->m_buffer[offset], color);
}
}
// --- SAMPLERS ---
inline void MemoryBufferColor::read(float *result, int x, int y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
if (clip_x || clip_y) {
/* clip result outside rect is zero */
zero_v4(result);
}
else
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
copy_v4_v4(result, &this->m_buffer[offset]);
}
}
inline void MemoryBufferColor::readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
BLI_assert(offset >= 0);
BLI_assert(offset < this->determineBufferSize() * NUMBER_OF_CHANNELS);
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) &&
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)));
copy_v4_v4(result, &this->m_buffer[offset]);
}
inline void MemoryBufferColor::readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
int x1 = floor(x);
int y1 = floor(y);
int x2 = x1 + 1;
int y2 = y1 + 1;
wrap_pixel(x1, y1, extend_x, extend_y);
wrap_pixel(x2, y2, extend_x, extend_y);
float valuex = x - x1;
float valuey = y - y1;
float mvaluex = 1.0f - valuex;
float mvaluey = 1.0f - valuey;
float color1[4];
float color2[4];
float color3[4];
float color4[4];
read(color1, x1, y1);
read(color2, x1, y2);
read(color3, x2, y1);
read(color4, x2, y2);
color1[0] = color1[0] * mvaluey + color2[0] * valuey;
color1[1] = color1[1] * mvaluey + color2[1] * valuey;
color1[2] = color1[2] * mvaluey + color2[2] * valuey;
color1[3] = color1[3] * mvaluey + color2[3] * valuey;
color3[0] = color3[0] * mvaluey + color4[0] * valuey;
color3[1] = color3[1] * mvaluey + color4[1] * valuey;
color3[2] = color3[2] * mvaluey + color4[2] * valuey;
color3[3] = color3[3] * mvaluey + color4[3] * valuey;
result[0] = color1[0] * mvaluex + color3[0] * valuex;
result[1] = color1[1] * mvaluex + color3[1] * valuex;
result[2] = color1[2] * mvaluex + color3[2] * valuex;
result[3] = color1[3] * mvaluex + color3[3] * valuex;
}
// --- EWA Filtering ---
// table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2
// used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible
#define EWA_MAXIDX 255
static const float EWA_WTS[EWA_MAXIDX + 1] = {
1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f,
0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f,
0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f,
0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f,
0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f,
0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f,
0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f,
0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f,
0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f,
0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f,
0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f,
0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f,
0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f,
0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f,
0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f,
0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f,
0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f,
0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f,
0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f,
0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f,
0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f,
0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f,
0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f,
0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f,
0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f,
0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f,
0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f,
0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f,
0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f,
0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f,
0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f,
0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f
};
static void ellipse_bounds(float A, float B, float C, float F, float &xmax, float &ymax)
{
float denom = 4.0f * A * C - B * B;
if (denom > 0.0f && A != 0.0f && C != 0.0f) {
xmax = sqrtf(F) / (2.0f * A) * (sqrtf(F * (4.0f * A - B * B / C)) + B * B * sqrtf(F / (C * denom)));
ymax = sqrtf(F) / (2.0f * C) * (sqrtf(F * (4.0f * C - B * B / A)) + B * B * sqrtf(F / (A * denom)));
}
else {
xmax = 0.0f;
ymax = 0.0f;
}
}
static void ellipse_params(float Ux, float Uy, float Vx, float Vy,
float &A, float &B, float &C, float &F, float &umax, float &vmax)
{
A = Vx * Vx + Vy * Vy;
B = -2.0f * (Ux * Vx + Uy * Vy);
C = Ux * Ux + Uy * Uy;
F = A * C - B * B * 0.25f;
float factor = (F != 0.0f ? (float)(EWA_MAXIDX + 1) / F : 0.0f);
A *= factor;
B *= factor;
C *= factor;
F = (float)(EWA_MAXIDX + 1);
ellipse_bounds(A, B, C, sqrtf(F), umax, vmax);
}
/**
* Filtering method based on
* "Creating raster omnimax images from multiple perspective views using the elliptical weighted average filter"
* by Ned Greene and Paul S. Heckbert (1986)
*/
void MemoryBufferColor::readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler)
{
zero_v4(result);
int width = this->getWidth(), height = this->getHeight();
if (width == 0 || height == 0)
return;
float u = uv[0], v = uv[1];
float Ux = derivatives[0][0], Vx = derivatives[1][0], Uy = derivatives[0][1], Vy = derivatives[1][1];
float A, B, C, F, ue, ve;
ellipse_params(Ux, Uy, Vx, Vy, A, B, C, F, ue, ve);
/* Note: highly eccentric ellipses can lead to large texture space areas to filter!
* This is limited somewhat by the EWA_WTS size in the loop, but a nicer approach
* could be the one found in
* "High Quality Elliptical Texture Filtering on GPU"
* by Pavlos Mavridis and Georgios Papaioannou
* in which the eccentricity of the ellipse is clamped.
*/
int U0 = (int)u;
int V0 = (int)v;
/* pixel offset for interpolation */
float ufac = u - floorf(u), vfac = v - floorf(v);
/* filter size */
int u1 = (int)(u - ue);
int u2 = (int)(u + ue);
int v1 = (int)(v - ve);
int v2 = (int)(v + ve);
/* sane clamping to avoid unnecessarily huge loops */
/* note: if eccentricity gets clamped (see above),
* the ue/ve limits can also be lowered accordingly
*/
if (U0 - u1 > EWA_MAXIDX) u1 = U0 - EWA_MAXIDX;
if (u2 - U0 > EWA_MAXIDX) u2 = U0 + EWA_MAXIDX;
if (V0 - v1 > EWA_MAXIDX) v1 = V0 - EWA_MAXIDX;
if (v2 - V0 > EWA_MAXIDX) v2 = V0 + EWA_MAXIDX;
float DDQ = 2.0f * A;
float U = u1 - U0;
float ac1 = A * (2.0f * U + 1.0f);
float ac2 = A * U * U;
float BU = B * U;
float sum = 0.0f;
for (int v = v1; v <= v2; ++v) {
float V = v - V0;
float DQ = ac1 + B * V;
float Q = (C * V + BU) * V + ac2;
for (int u = u1; u <= u2; ++u) {
if (Q < F) {
float tc[4];
const float wt = EWA_WTS[CLAMPIS((int)Q, 0, EWA_MAXIDX)];
switch (sampler) {
case COM_PS_NEAREST: read(tc, u, v); break;
case COM_PS_BILINEAR: readBilinear(tc, (float)u + ufac, (float)v + vfac); break;
case COM_PS_BICUBIC: readBilinear(tc, (float)u + ufac, (float)v + vfac); break; /* XXX no readBicubic method yet */
default: zero_v4(tc); break;
}
madd_v4_v4fl(result, tc, wt);
sum += wt;
}
Q += DQ;
DQ += DDQ;
}
}
mul_v4_fl(result, (sum != 0.0f ? 1.0f / sum : 0.0f));
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2014, 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
*/
class MemoryBufferColor;
#ifndef _COM_MemoryBufferColor_h_
#define _COM_MemoryBufferColor_h_
#include "COM_MemoryBuffer.h"
class MemoryBufferColor: MemoryBuffer
{
protected:
/**
* @brief construct new MemoryBuffer for a chunk
*/
MemoryBufferColor(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
/**
* @brief construct new temporarily MemoryBuffer for an area
*/
MemoryBufferColor(MemoryProxy *memoryProxy, rcti *rect);
MemoryBufferColor(DataType datatype, rcti *rect);
public:
void writePixel(int x, int y, const float *color);
void addPixel(int x, int y, const float *color);
void read(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler);
MemoryBuffer *duplicate();
friend class MemoryBuffer;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBufferColor")
#endif
};
#endif

View File

@@ -0,0 +1,152 @@
/*
* Copyright 2014, 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
*/
#include "COM_MemoryBufferValue.h"
#define NUMBER_OF_CHANNELS COM_NO_CHANNELS_VALUE
MemoryBufferValue::MemoryBufferValue(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect):
MemoryBuffer(memoryProxy, chunkNumber, rect, NUMBER_OF_CHANNELS)
{
}
MemoryBufferValue::MemoryBufferValue(MemoryProxy *memoryProxy, rcti *rect) :
MemoryBuffer(memoryProxy, rect, NUMBER_OF_CHANNELS)
{
}
MemoryBufferValue::MemoryBufferValue(DataType datatype, rcti *rect) :
MemoryBuffer(datatype, rect, NUMBER_OF_CHANNELS) {
}
MemoryBuffer *MemoryBufferValue::duplicate()
{
MemoryBufferValue *result = new MemoryBufferValue(this->m_memoryProxy, &this->m_rect);
memcpy(result->getBuffer(), this->getBuffer(), this->determineBufferSize() * NUMBER_OF_CHANNELS * sizeof(float));
return result;
}
// --- write pixels ---
void MemoryBufferValue::writePixel(int x, int y, const float *color)
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
y >= this->m_rect.ymin && y < this->m_rect.ymax)
{
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * NUMBER_OF_CHANNELS;
copy_v4_v4(&this->m_buffer[offset], color);
}
}
void MemoryBufferValue::addPixel(int x, int y, const float *color)
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
y >= this->m_rect.ymin && y < this->m_rect.ymax)
{
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * NUMBER_OF_CHANNELS;
this->m_buffer[offset] = color[0];
}
}
// --- SAMPLERS ---
inline void MemoryBufferValue::read(float *result, int x, int y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
if (clip_x || clip_y) {
/* clip result outside rect is zero */
zero_v4(result);
}
else
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
result[0] = this->m_buffer[offset];
}
}
inline void MemoryBufferValue::readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
BLI_assert(offset >= 0);
BLI_assert(offset < this->determineBufferSize() * NUMBER_OF_CHANNELS);
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) &&
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)));
result[0] = this->m_buffer[offset];
}
inline void MemoryBufferValue::readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
int x1 = floor(x);
int y1 = floor(y);
int x2 = x1 + 1;
int y2 = y1 + 1;
wrap_pixel(x1, y1, extend_x, extend_y);
wrap_pixel(x2, y2, extend_x, extend_y);
float valuex = x - x1;
float valuey = y - y1;
float mvaluex = 1.0f - valuex;
float mvaluey = 1.0f - valuey;
float value1;
float value2;
float value3;
float value4;
read(&value1, x1, y1);
read(&value2, x1, y2);
read(&value3, x2, y1);
read(&value4, x2, y2);
value1 = value1 * mvaluey + value2 * valuey;
value3 = value3 * mvaluey + value4 * valuey;
result[0] = value1 * mvaluex + value3 * valuex;
}
float MemoryBufferValue::getMaximumValue() const
{
float result = this->m_buffer[0];
const unsigned int size = this->determineBufferSize();
unsigned int i;
const float *fp_src = this->m_buffer;
for (i = 0; i < size; i++, fp_src += NUMBER_OF_CHANNELS) {
float value = *fp_src;
if (value > result) {
result = value;
}
}
return result;
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2014, 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
*/
class MemoryBufferValue;
#ifndef _COM_MemoryBufferValue_h_
#define _COM_MemoryBufferValue_h_
#include "COM_MemoryBuffer.h"
class MemoryBufferValue: public MemoryBuffer
{
protected:
/**
* @brief construct new MemoryBuffer for a chunk
*/
MemoryBufferValue(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
/**
* @brief construct new temporarily MemoryBuffer for an area
*/
MemoryBufferValue(MemoryProxy *memoryProxy, rcti *rect);
MemoryBufferValue(DataType datatype, rcti *rect);
public:
void writePixel(int x, int y, const float *color);
void addPixel(int x, int y, const float *color);
void read(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
float getMaximumValue() const;
MemoryBuffer *duplicate();
friend class MemoryBuffer;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBufferValue")
#endif
};
#endif

View File

@@ -0,0 +1,144 @@
/*
* Copyright 2014, 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
*/
#include "COM_MemoryBufferVector.h"
#define NUMBER_OF_CHANNELS COM_NO_CHANNELS_VECTOR
MemoryBufferVector::MemoryBufferVector(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect):
MemoryBuffer(memoryProxy, chunkNumber, rect, NUMBER_OF_CHANNELS)
{
}
MemoryBufferVector::MemoryBufferVector(MemoryProxy *memoryProxy, rcti *rect) :
MemoryBuffer(memoryProxy, rect, NUMBER_OF_CHANNELS)
{
}
MemoryBufferVector::MemoryBufferVector(DataType datatype, rcti *rect) :
MemoryBuffer(datatype, rect, NUMBER_OF_CHANNELS) {
}
MemoryBuffer *MemoryBufferVector::duplicate()
{
MemoryBufferVector *result = new MemoryBufferVector(this->m_memoryProxy, &this->m_rect);
memcpy(result->getBuffer(), this->getBuffer(), this->determineBufferSize() * NUMBER_OF_CHANNELS * sizeof(float));
return result;
}
// --- write pixels ---
void MemoryBufferVector::writePixel(int x, int y, const float *color)
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
y >= this->m_rect.ymin && y < this->m_rect.ymax)
{
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * NUMBER_OF_CHANNELS;
copy_v4_v4(&this->m_buffer[offset], color);
}
}
void MemoryBufferVector::addPixel(int x, int y, const float *color)
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
y >= this->m_rect.ymin && y < this->m_rect.ymax)
{
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * NUMBER_OF_CHANNELS;
add_v4_v4(&this->m_buffer[offset], color);
}
}
// --- SAMPLERS ---
inline void MemoryBufferVector::read(float *result, int x, int y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
if (clip_x || clip_y) {
/* clip result outside rect is zero */
zero_v4(result);
}
else
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
copy_v4_v4(result, &this->m_buffer[offset]);
}
}
inline void MemoryBufferVector::readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
BLI_assert(offset >= 0);
BLI_assert(offset < this->determineBufferSize() * NUMBER_OF_CHANNELS);
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) &&
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)));
copy_v4_v4(result, &this->m_buffer[offset]);
}
inline void MemoryBufferVector::readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
int x1 = floor(x);
int y1 = floor(y);
int x2 = x1 + 1;
int y2 = y1 + 1;
wrap_pixel(x1, y1, extend_x, extend_y);
wrap_pixel(x2, y2, extend_x, extend_y);
float valuex = x - x1;
float valuey = y - y1;
float mvaluex = 1.0f - valuex;
float mvaluey = 1.0f - valuey;
float vector1[NUMBER_OF_CHANNELS];
float vector2[NUMBER_OF_CHANNELS];
float vector3[NUMBER_OF_CHANNELS];
float vector4[NUMBER_OF_CHANNELS];
read(vector1, x1, y1);
read(vector2, x1, y2);
read(vector3, x2, y1);
read(vector4, x2, y2);
vector1[0] = vector1[0] * mvaluey + vector2[0] * valuey;
vector1[1] = vector1[1] * mvaluey + vector2[1] * valuey;
vector1[2] = vector1[2] * mvaluey + vector2[2] * valuey;
vector3[0] = vector3[0] * mvaluey + vector4[0] * valuey;
vector3[1] = vector3[1] * mvaluey + vector4[1] * valuey;
vector3[2] = vector3[2] * mvaluey + vector4[2] * valuey;
result[0] = vector1[0] * mvaluex + vector3[0] * valuex;
result[1] = vector1[1] * mvaluex + vector3[1] * valuex;
result[2] = vector1[2] * mvaluex + vector3[2] * valuex;
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2014, 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
*/
class MemoryBufferVector;
#ifndef _COM_MemoryBufferVector_h_
#define _COM_MemoryBufferVector_h_
#include "COM_MemoryBuffer.h"
class MemoryBufferVector: public MemoryBuffer
{
protected:
/**
* @brief construct new MemoryBuffer for a chunk
*/
MemoryBufferVector(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
/**
* @brief construct new temporarily MemoryBuffer for an area
*/
MemoryBufferVector(MemoryProxy *memoryProxy, rcti *rect);
MemoryBufferVector(DataType datatype, rcti *rect);
public:
void writePixel(int x, int y, const float *color);
void addPixel(int x, int y, const float *color);
void read(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
MemoryBuffer *duplicate();
friend class MemoryBuffer;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBufferVector")
#endif
};
#endif

View File

@@ -23,10 +23,11 @@
#include "COM_MemoryProxy.h" #include "COM_MemoryProxy.h"
MemoryProxy::MemoryProxy() MemoryProxy::MemoryProxy(DataType type)
{ {
this->m_writeBufferOperation = NULL; this->m_writeBufferOperation = NULL;
this->m_executor = NULL; this->m_executor = NULL;
this->m_datatype = type;
} }
void MemoryProxy::allocate(unsigned int width, unsigned int height) void MemoryProxy::allocate(unsigned int width, unsigned int height)
@@ -37,7 +38,7 @@ void MemoryProxy::allocate(unsigned int width, unsigned int height)
result.ymin = 0; result.ymin = 0;
result.ymax = height; result.ymax = height;
this->m_buffer = new MemoryBuffer(this, 1, &result); this->m_buffer = MemoryBuffer::create(this, 1, &result);
} }
void MemoryProxy::free() void MemoryProxy::free()

View File

@@ -47,12 +47,7 @@ private:
* @brief reference to the executor. the Execution group that can fill a chunk * @brief reference to the executor. the Execution group that can fill a chunk
*/ */
ExecutionGroup *m_executor; ExecutionGroup *m_executor;
/**
* @brief datatype of this MemoryProxy
*/
/* DataType m_datatype; */ /* UNUSED */
/** /**
* @brief channel information of this buffer * @brief channel information of this buffer
*/ */
@@ -63,8 +58,13 @@ private:
*/ */
MemoryBuffer *m_buffer; MemoryBuffer *m_buffer;
/**
* @brief datatype of this MemoryProxy
*/
DataType m_datatype;
public: public:
MemoryProxy(); MemoryProxy(DataType type);
/** /**
* @brief set the ExecutionGroup that can be scheduled to calculate a certain chunk. * @brief set the ExecutionGroup that can be scheduled to calculate a certain chunk.
@@ -104,6 +104,8 @@ public:
*/ */
inline MemoryBuffer *getBuffer() { return this->m_buffer; } inline MemoryBuffer *getBuffer() { return this->m_buffer; }
inline DataType getDataType() { return this->m_datatype; }
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryProxy") MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryProxy")
#endif #endif

View File

@@ -448,7 +448,7 @@ void NodeOperationBuilder::add_input_buffers(NodeOperation *operation, NodeOpera
/* check of other end already has write operation, otherwise add a new one */ /* check of other end already has write operation, otherwise add a new one */
WriteBufferOperation *writeoperation = find_attached_write_buffer_operation(output); WriteBufferOperation *writeoperation = find_attached_write_buffer_operation(output);
if (!writeoperation) { if (!writeoperation) {
writeoperation = new WriteBufferOperation(); writeoperation = new WriteBufferOperation(output->getDataType());
writeoperation->setbNodeTree(m_context->getbNodeTree()); writeoperation->setbNodeTree(m_context->getbNodeTree());
addOperation(writeoperation); addOperation(writeoperation);
@@ -458,7 +458,7 @@ void NodeOperationBuilder::add_input_buffers(NodeOperation *operation, NodeOpera
} }
/* add readbuffer op for the input */ /* add readbuffer op for the input */
ReadBufferOperation *readoperation = new ReadBufferOperation(); ReadBufferOperation *readoperation = new ReadBufferOperation(output->getDataType());
readoperation->setMemoryProxy(writeoperation->getMemoryProxy()); readoperation->setMemoryProxy(writeoperation->getMemoryProxy());
this->addOperation(readoperation); this->addOperation(readoperation);
@@ -491,7 +491,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOper
/* if no write buffer operation exists yet, create a new one */ /* if no write buffer operation exists yet, create a new one */
if (!writeOperation) { if (!writeOperation) {
writeOperation = new WriteBufferOperation(); writeOperation = new WriteBufferOperation(operation->getOutputSocket()->getDataType());
writeOperation->setbNodeTree(m_context->getbNodeTree()); writeOperation->setbNodeTree(m_context->getbNodeTree());
addOperation(writeOperation); addOperation(writeOperation);
@@ -506,7 +506,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOper
if (&target->getOperation() == writeOperation) if (&target->getOperation() == writeOperation)
continue; /* skip existing write op links */ continue; /* skip existing write op links */
ReadBufferOperation *readoperation = new ReadBufferOperation(); ReadBufferOperation *readoperation = new ReadBufferOperation(operation->getOutputSocket()->getDataType());
readoperation->setMemoryProxy(writeOperation->getMemoryProxy()); readoperation->setMemoryProxy(writeOperation->getMemoryProxy());
addOperation(readoperation); addOperation(readoperation);

View File

@@ -24,6 +24,18 @@
#include "COM_WorkScheduler.h" #include "COM_WorkScheduler.h"
typedef enum COM_VendorID {NVIDIA = 0x10DE, AMD = 0x1002} COM_VendorID; typedef enum COM_VendorID {NVIDIA = 0x10DE, AMD = 0x1002} COM_VendorID;
const cl_image_format IMAGE_FORMAT_COLOR = {
CL_RGBA,
CL_FLOAT
};
const cl_image_format IMAGE_FORMAT_VECTOR = {
CL_RGB,
CL_FLOAT
};
const cl_image_format IMAGE_FORMAT_VALUE = {
CL_R,
CL_FLOAT
};
OpenCLDevice::OpenCLDevice(cl_context context, cl_device_id device, cl_program program, cl_int vendorId) OpenCLDevice::OpenCLDevice(cl_context context, cl_device_id device, cl_program program, cl_int vendorId)
{ {
@@ -72,6 +84,21 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel,
return COM_clAttachMemoryBufferToKernelParameter(kernel, parameterIndex, offsetIndex, cleanup, inputMemoryBuffers, (ReadBufferOperation *)reader); return COM_clAttachMemoryBufferToKernelParameter(kernel, parameterIndex, offsetIndex, cleanup, inputMemoryBuffers, (ReadBufferOperation *)reader);
} }
const cl_image_format* OpenCLDevice::determineImageFormat(MemoryBuffer *memoryBuffer)
{
const cl_image_format *imageFormat;
int no_channels = memoryBuffer->get_no_channels();
if (no_channels == 1) {
imageFormat = &IMAGE_FORMAT_VALUE;
} else if (no_channels == 3) {
imageFormat = &IMAGE_FORMAT_VECTOR;
} else {
imageFormat = &IMAGE_FORMAT_COLOR;
}
return imageFormat;
}
cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex, cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex,
list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers,
ReadBufferOperation *reader) ReadBufferOperation *reader)
@@ -80,12 +107,9 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel,
MemoryBuffer *result = reader->getInputMemoryBuffer(inputMemoryBuffers); MemoryBuffer *result = reader->getInputMemoryBuffer(inputMemoryBuffers);
const cl_image_format imageFormat = { const cl_image_format *imageFormat = determineImageFormat(result);
CL_RGBA,
CL_FLOAT
};
cl_mem clBuffer = clCreateImage2D(this->m_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &imageFormat, result->getWidth(), cl_mem clBuffer = clCreateImage2D(this->m_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, imageFormat, result->getWidth(),
result->getHeight(), 0, result->getBuffer(), &error); result->getHeight(), 0, result->getBuffer(), &error);
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
@@ -192,5 +216,4 @@ cl_kernel OpenCLDevice::COM_clCreateKernel(const char *kernelname, list<cl_kerne
if (clKernelsToCleanUp) clKernelsToCleanUp->push_back(kernel); if (clKernelsToCleanUp) clKernelsToCleanUp->push_back(kernel);
} }
return kernel; return kernel;
} }

View File

@@ -94,6 +94,13 @@ public:
*/ */
void execute(WorkPackage *work); void execute(WorkPackage *work);
/**
* @brief determine an image format
* @param memorybuffer
*/
static const cl_image_format* determineImageFormat(MemoryBuffer *memoryBuffer);
cl_context getContext() { return this->m_context; } cl_context getContext() { return this->m_context; }
cl_command_queue getQueue() { return this->m_queue; } cl_command_queue getQueue() { return this->m_queue; }

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2011, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_OutputSocket_h
#define _COM_OutputSocket_h
#include <vector>
#include "COM_Socket.h"
using namespace std;
class SocketConnection;
class Node;
class InputSocket;
class WriteBufferOperation;
//#define COM_ST_INPUT 0
//#define COM_ST_OUTPUT 1
/**
* @brief OutputSocket are sockets that can send data/input
* @ingroup Model
*/
class OutputSocket : public Socket {
private:
vector<SocketConnection *> m_connections;
void removeFirstConnection();
public:
OutputSocket(DataType datatype);
OutputSocket(DataType datatype, int inputSocketDataTypeDeterminatorIndex);
OutputSocket(OutputSocket *from);
void addConnection(SocketConnection *connection);
void removeConnection(SocketConnection *connection);
SocketConnection *getConnection(unsigned int index) { return this->m_connections[index]; }
const int isConnected() const;
int isOutputSocket() const;
/**
* @brief determine the resolution of this socket
* @param resolution the result of this operation
* @param preferredResolution the preferable resolution as no resolution could be determined
*/
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
/**
* @brief determine the actual data type and channel info.
*/
void relinkConnections(OutputSocket *relinkToSocket) { this->relinkConnections(relinkToSocket, false); }
void relinkConnections(OutputSocket *relinkToSocket, bool single);
const int getNumberOfConnections() { return this->m_connections.size(); }
void clearConnections();
/**
* @brief find a connected write buffer operation to this OutputSocket
* @return WriteBufferOperation or NULL
*/
WriteBufferOperation *findAttachedWriteBufferOperation() const;
ChannelInfo *getChannelInfo(const int channelnumber);
private:
};
#endif

View File

@@ -0,0 +1,126 @@
/*
* Copyright 2011, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_SocketConnection_h
#define _COM_SocketConnection_h
#include "DNA_node_types.h"
#include "COM_Node.h"
#include "COM_Socket.h"
/**
* @brief An SocketConnection is an connection between an InputSocket and an OutputSocket.
*
* <pre>
* +----------+ To InputSocket +----------+
* | From | SocketConnection \| To Node |
* | Node *====================* |
* | |\ | |
* | | From OutputSocket +----------+
* +----------+
* </pre>
* @ingroup Model
* @see InputSocket
* @see OutputSocket
*/
class SocketConnection {
private:
/**
* @brief Startpoint of the connection
*/
OutputSocket *m_fromSocket;
/**
* @brief Endpoint of the connection
*/
InputSocket *m_toSocket;
/**
* @brief has the resize already been done for this connection
*/
bool m_ignoreResizeCheck;
public:
SocketConnection();
/**
* @brief set the startpoint of the connection
* @param fromsocket
*/
void setFromSocket(OutputSocket *fromsocket);
/**
* @brief get the startpoint of the connection
* @return from OutputSocket
*/
OutputSocket *getFromSocket() const;
/**
* @brief set the endpoint of the connection
* @param tosocket
*/
void setToSocket(InputSocket *tosocket);
/**
* @brief get the endpoint of the connection
* @return to InputSocket
*/
InputSocket *getToSocket() const;
/**
* @brief check if this connection is valid
*/
bool isValid() const;
/**
* @brief return the Node where this connection is connected from
*/
NodeBase *getFromNode() const;
/**
* @brief return the Node where this connection is connected to
*/
NodeBase *getToNode() const;
/**
* @brief set, whether the resize has already been done for this SocketConnection
*/
void setIgnoreResizeCheck(bool check) { this->m_ignoreResizeCheck = check; }
/**
* @brief has the resize already been done for this SocketConnection
*/
bool isIgnoreResizeCheck() const { return this->m_ignoreResizeCheck; }
/**
* @brief does this SocketConnection need resolution conversion
* @note PreviewOperation's will be ignored
* @note Already converted SocketConnection's will be ignored
* @return needs conversion [true:false]
*/
bool needsResolutionConversion() const;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:SocketConnection")
#endif
};
#endif

View File

@@ -71,8 +71,9 @@ void SocketBufferNode::convertToOperations(NodeConverter &converter, const Compo
NodeOutput *output = this->getOutputSocket(0); NodeOutput *output = this->getOutputSocket(0);
NodeInput *input = this->getInputSocket(0); NodeInput *input = this->getInputSocket(0);
WriteBufferOperation *writeOperation = new WriteBufferOperation(); DataType datatype = output->getDataType();
ReadBufferOperation *readOperation = new ReadBufferOperation(); WriteBufferOperation *writeOperation = new WriteBufferOperation(datatype);
ReadBufferOperation *readOperation = new ReadBufferOperation(datatype);
readOperation->setMemoryProxy(writeOperation->getMemoryProxy()); readOperation->setMemoryProxy(writeOperation->getMemoryProxy());
converter.addOperation(writeOperation); converter.addOperation(writeOperation);
converter.addOperation(readOperation); converter.addOperation(readOperation);

View File

@@ -57,8 +57,8 @@ void TranslateNode::convertToOperations(NodeConverter &converter, const Composit
converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0)); converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
if (data->wrap_axis) { if (data->wrap_axis) {
WriteBufferOperation *writeOperation = new WriteBufferOperation(); WriteBufferOperation *writeOperation = new WriteBufferOperation(COM_DT_COLOR);
WrapOperation *wrapOperation = new WrapOperation(); WrapOperation *wrapOperation = new WrapOperation(COM_DT_COLOR);
wrapOperation->setMemoryProxy(writeOperation->getMemoryProxy()); wrapOperation->setMemoryProxy(writeOperation->getMemoryProxy());
wrapOperation->setWrapping(data->wrap_axis); wrapOperation->setWrapping(data->wrap_axis);

View File

@@ -95,7 +95,7 @@ void *AntiAliasOperation::initializeTileData(rcti *rect)
float *input = tile->getBuffer(); float *input = tile->getBuffer();
char *valuebuffer = (char *)MEM_mallocN(sizeof(char) * size, __func__); char *valuebuffer = (char *)MEM_mallocN(sizeof(char) * size, __func__);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
float in = input[i * COM_NUMBER_OF_CHANNELS]; float in = input[i];
valuebuffer[i] = FTOCHAR(in); valuebuffer[i] = FTOCHAR(in);
} }
antialias_tagbuf(tile->getWidth(), tile->getHeight(), valuebuffer); antialias_tagbuf(tile->getWidth(), tile->getHeight(), valuebuffer);

View File

@@ -138,7 +138,7 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int y2 = rect->ymax; int y2 = rect->ymax;
int offset = (y1 * this->getWidth() + x1); int offset = (y1 * this->getWidth() + x1);
int add = (this->getWidth() - (x2 - x1)); int add = (this->getWidth() - (x2 - x1));
int offset4 = offset * COM_NUMBER_OF_CHANNELS; int offset4 = offset * COM_NO_CHANNELS_COLOR;
int x; int x;
int y; int y;
bool breaked = false; bool breaked = false;
@@ -196,14 +196,14 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber)
this->m_depthInput->readSampled(color, input_x, input_y, COM_PS_NEAREST); this->m_depthInput->readSampled(color, input_x, input_y, COM_PS_NEAREST);
zbuffer[offset] = color[0]; zbuffer[offset] = color[0];
offset4 += COM_NUMBER_OF_CHANNELS; offset4 += COM_NO_CHANNELS_COLOR;
offset++; offset++;
if (isBreaked()) { if (isBreaked()) {
breaked = true; breaked = true;
} }
} }
offset += add; offset += add;
offset4 += add * COM_NUMBER_OF_CHANNELS; offset4 += add * COM_NO_CHANNELS_COLOR;
} }
} }

View File

@@ -22,7 +22,6 @@
#include "COM_ConvertOperation.h" #include "COM_ConvertOperation.h"
ConvertBaseOperation::ConvertBaseOperation() ConvertBaseOperation::ConvertBaseOperation()
{ {
this->m_inputOperation = NULL; this->m_inputOperation = NULL;
@@ -49,9 +48,9 @@ ConvertValueToColorOperation::ConvertValueToColorOperation() : ConvertBaseOperat
void ConvertValueToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) void ConvertValueToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{ {
float inputValue[4]; float value;
this->m_inputOperation->readSampled(inputValue, x, y, sampler); this->m_inputOperation->readSampled(&value, x, y, sampler);
output[0] = output[1] = output[2] = inputValue[0]; output[0] = output[1] = output[2] = value;
output[3] = 1.0f; output[3] = 1.0f;
} }
@@ -98,7 +97,9 @@ ConvertColorToVectorOperation::ConvertColorToVectorOperation() : ConvertBaseOper
void ConvertColorToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) 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);
} }
@@ -112,12 +113,9 @@ ConvertValueToVectorOperation::ConvertValueToVectorOperation() : ConvertBaseOper
void ConvertValueToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) void ConvertValueToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{ {
float input[4]; float value;
this->m_inputOperation->readSampled(input, x, y, sampler); this->m_inputOperation->readSampled(&value, x, y, sampler);
output[0] = input[0]; output[0] = output[1] = output[2] = value;
output[1] = input[0];
output[2] = input[0];
output[3] = 0.0f;
} }
@@ -131,7 +129,7 @@ ConvertVectorToColorOperation::ConvertVectorToColorOperation() : ConvertBaseOper
void ConvertVectorToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) void ConvertVectorToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{ {
this->m_inputOperation->readSampled(output, x, y, sampler); this->m_inputOperation->readSampled(output, x, y, sampler);
output[3] = 1.0f; output[3] = 1.0f;
} }

View File

@@ -82,18 +82,18 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y,
const int bufferWidth = BLI_rcti_size_x(rect); const int bufferWidth = BLI_rcti_size_x(rect);
int offset; int offset;
this->m_inputProgram->read(inputValue, x, y, NULL); inputBuffer->read(inputValue, x, y);
if (inputValue[0] > sw) { if (inputValue[0] > sw) {
for (int yi = miny; yi < maxy; yi++) { for (int yi = miny; yi < maxy; yi++) {
const float dy = yi - y; 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++) { for (int xi = minx; xi < maxx; xi++) {
if (buffer[offset] < sw) { if (buffer[offset] < sw) {
const float dx = xi - x; const float dx = xi - x;
const float dis = dx * dx + dy * dy; const float dis = dx * dx + dy * dy;
mindist = min(mindist, dis); mindist = min(mindist, dis);
} }
offset += 4; offset ++;
} }
} }
pixelvalue = -sqrtf(mindist); pixelvalue = -sqrtf(mindist);
@@ -101,14 +101,14 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y,
else { else {
for (int yi = miny; yi < maxy; yi++) { for (int yi = miny; yi < maxy; yi++) {
const float dy = yi - y; 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++) { for (int xi = minx; xi < maxx; xi++) {
if (buffer[offset] > sw) { if (buffer[offset] > sw) {
const float dx = xi - x; const float dx = xi - x;
const float dis = dx * dx + dy * dy; const float dis = dx * dx + dy * dy;
mindist = min(mindist, dis); mindist = min(mindist, dis);
} }
offset += 4; offset ++;
} }
} }
@@ -193,7 +193,7 @@ void DilateDistanceOperation::executePixel(float output[4], int x, int y, void *
const float mindist = distance * distance; const float mindist = distance * distance;
MemoryBuffer *inputBuffer = (MemoryBuffer *)data; MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
float *buffer = inputBuffer->getBuffer(); float *buffer = inputBuffer->getBuffer();
rcti *rect = inputBuffer->getRect(); rcti *rect = inputBuffer->getRect();
const int minx = max(x - this->m_scope, rect->xmin); const int minx = max(x - this->m_scope, rect->xmin);
const int miny = max(y - this->m_scope, rect->ymin); const int miny = max(y - this->m_scope, rect->ymin);
@@ -206,17 +206,17 @@ void DilateDistanceOperation::executePixel(float output[4], int x, int y, void *
for (int yi = miny; yi < maxy; yi++) { for (int yi = miny; yi < maxy; yi++) {
const float dy = yi - y; 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++) { for (int xi = minx; xi < maxx; xi++) {
const float dx = xi - x; const float dx = xi - x;
const float dis = dx * dx + dy * dy; const float dis = dx * dx + dy * dy;
if (dis <= mindist) { if (dis <= mindist) {
value = max(buffer[offset], value); value = max(buffer[offset], value);
} }
offset += 4; offset ++;
} }
} }
output[0] = value; output[0] = value;
} }
void DilateDistanceOperation::deinitExecution() void DilateDistanceOperation::deinitExecution()
@@ -280,14 +280,14 @@ void ErodeDistanceOperation::executePixel(float output[4], int x, int y, void *d
for (int yi = miny; yi < maxy; yi++) { for (int yi = miny; yi < maxy; yi++) {
const float dy = yi - y; 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++) { for (int xi = minx; xi < maxx; xi++) {
const float dx = xi - x; const float dx = xi - x;
const float dis = dx * dx + dy * dy; const float dis = dx * dx + dy * dy;
if (dis <= mindist) { if (dis <= mindist) {
value = min(buffer[offset], value); value = min(buffer[offset], value);
} }
offset += 4; offset ++;
} }
} }
output[0] = value; output[0] = value;
@@ -383,7 +383,7 @@ void *DilateStepOperation::initializeTileData(rcti *rect)
buf[x] = -MAXFLOAT; buf[x] = -MAXFLOAT;
} }
for (x = xmin; x < xmax; ++x) { 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++) { for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {
@@ -510,7 +510,7 @@ void *ErodeStepOperation::initializeTileData(rcti *rect)
buf[x] = MAXFLOAT; buf[x] = MAXFLOAT;
} }
for (x = xmin; x < xmax; ++x) { 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++) { for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {

View File

@@ -129,16 +129,16 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
this->m_sy = this->m_data.sizey * this->m_size / 2.0f; this->m_sy = this->m_data.sizey * this->m_size / 2.0f;
if ((this->m_sx == this->m_sy) && (this->m_sx > 0.f)) { 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_NO_CHANNELS_COLOR; ++c)
IIR_gauss(copy, this->m_sx, c, 3); IIR_gauss(copy, this->m_sx, c, 3);
} }
else { else {
if (this->m_sx > 0.0f) { if (this->m_sx > 0.0f) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
IIR_gauss(copy, this->m_sx, c, 1); IIR_gauss(copy, this->m_sx, c, 1);
} }
if (this->m_sy > 0.0f) { if (this->m_sy > 0.0f) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
IIR_gauss(copy, this->m_sy, c, 2); IIR_gauss(copy, this->m_sy, c, 2);
} }
} }
@@ -170,7 +170,7 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
dai.ymin = max(dai.ymin, buf_rect->ymin); dai.ymin = max(dai.ymin, buf_rect->ymin);
dai.ymax = min(dai.ymax, buf_rect->ymax); dai.ymax = min(dai.ymax, buf_rect->ymax);
MemoryBuffer *tile = new MemoryBuffer(NULL, &dai); MemoryBuffer *tile = MemoryBuffer::create(COM_DT_COLOR, &dai);
tile->copyContentFrom(buffer); tile->copyContentFrom(buffer);
int c; int c;
@@ -178,16 +178,16 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
float sy = this->m_data.sizey * this->m_size / 2.0f; float sy = this->m_data.sizey * this->m_size / 2.0f;
if ((sx == sy) && (sx > 0.f)) { if ((sx == sy) && (sx > 0.f)) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
IIR_gauss(tile, sx, c, 3); IIR_gauss(tile, sx, c, 3);
} }
else { else {
if (sx > 0.0f) { if (sx > 0.0f) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
IIR_gauss(tile, sx, c, 1); IIR_gauss(tile, sx, c, 1);
} }
if (sy > 0.0f) { if (sy > 0.0f) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
IIR_gauss(tile, sy, c, 2); IIR_gauss(tile, sy, c, 2);
} }
} }
@@ -217,6 +217,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign
unsigned int x, y, sz; unsigned int x, y, sz;
unsigned int i; unsigned int i;
float *buffer = src->getBuffer(); float *buffer = src->getBuffer();
const unsigned int no_channels = src->get_no_channels();
// <0.5 not valid, though can have a possibly useful sort of sharpening effect // <0.5 not valid, though can have a possibly useful sort of sharpening effect
if (sigma < 0.5f) return; if (sigma < 0.5f) return;
@@ -295,31 +296,31 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign
int offset; int offset;
for (y = 0; y < src_height; ++y) { for (y = 0; y < src_height; ++y) {
const int yx = y * src_width; const int yx = y * src_width;
offset = yx * COM_NUMBER_OF_CHANNELS + chan; offset = yx * no_channels + chan;
for (x = 0; x < src_width; ++x) { for (x = 0; x < src_width; ++x) {
X[x] = buffer[offset]; X[x] = buffer[offset];
offset += COM_NUMBER_OF_CHANNELS; offset += no_channels;
} }
YVV(src_width); YVV(src_width);
offset = yx * COM_NUMBER_OF_CHANNELS + chan; offset = yx * no_channels + chan;
for (x = 0; x < src_width; ++x) { for (x = 0; x < src_width; ++x) {
buffer[offset] = Y[x]; buffer[offset] = Y[x];
offset += COM_NUMBER_OF_CHANNELS; offset += no_channels;
} }
} }
} }
if (xy & 2) { // V if (xy & 2) { // V
int offset; int offset;
const int add = src_width * COM_NUMBER_OF_CHANNELS; const int add = src_width * no_channels;
for (x = 0; x < src_width; ++x) { for (x = 0; x < src_width; ++x) {
offset = x * COM_NUMBER_OF_CHANNELS + chan; offset = x * no_channels + chan;
for (y = 0; y < src_height; ++y) { for (y = 0; y < src_height; ++y) {
X[y] = buffer[offset]; X[y] = buffer[offset];
offset += add; offset += add;
} }
YVV(src_height); YVV(src_height);
offset = x * COM_NUMBER_OF_CHANNELS + chan; offset = x * no_channels + chan;
for (y = 0; y < src_height; ++y) { for (y = 0; y < src_height; ++y) {
buffer[offset] = Y[y]; buffer[offset] = Y[y];
offset += add; offset += add;
@@ -395,7 +396,7 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect)
if (this->m_overlay == FAST_GAUSS_OVERLAY_MIN) { if (this->m_overlay == FAST_GAUSS_OVERLAY_MIN) {
float *src = newBuf->getBuffer(); float *src = newBuf->getBuffer();
float *dst = copy->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_NO_CHANNELS_VALUE, dst += COM_NO_CHANNELS_VALUE) {
if (*src < *dst) { if (*src < *dst) {
*dst = *src; *dst = *src;
} }
@@ -404,15 +405,13 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect)
else if (this->m_overlay == FAST_GAUSS_OVERLAY_MAX) { else if (this->m_overlay == FAST_GAUSS_OVERLAY_MAX) {
float *src = newBuf->getBuffer(); float *src = newBuf->getBuffer();
float *dst = copy->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_NO_CHANNELS_VALUE, dst += COM_NO_CHANNELS_VALUE) {
if (*src > *dst) { if (*src > *dst) {
*dst = *src; *dst = *src;
} }
} }
} }
// newBuf->
this->m_iirgaus = copy; this->m_iirgaus = copy;
} }
unlockMutex(); unlockMutex();

View File

@@ -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' *** */ /* *** this is the main part which is different to 'GaussianXBlurOperation' *** */
int step = getStep(); int step = getStep();
int offsetadd = getOffsetAdd(); int bufferindex = ((xmin - bufferstartx)) + ((ymin - bufferstarty) * bufferwidth);
int bufferindex = ((xmin - bufferstartx) * 4) + ((ymin - bufferstarty) * 4 * bufferwidth);
/* gauss */ /* gauss */
float alpha_accum = 0.0f; float alpha_accum = 0.0f;
float multiplier_accum = 0.0f; float multiplier_accum = 0.0f;
/* dilate */ /* 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 */ float distfacinv_max = 1.0f; /* 0 to 1 */
for (int nx = xmin; nx < xmax; nx += step) { 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; distfacinv_max = multiplier;
} }
} }
bufferindex += offsetadd; bufferindex += step;
} }
/* blend between the max value and gauss blue - gives nice feather */ /* blend between the max value and gauss blue - gives nice feather */

View File

@@ -108,11 +108,11 @@ void GaussianAlphaYBlurOperation::executePixel(float output[4], int x, int y, vo
float multiplier_accum = 0.0f; float multiplier_accum = 0.0f;
/* dilate */ /* 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 */ float distfacinv_max = 1.0f; /* 0 to 1 */
for (int ny = ymin; ny < ymax; ny += step) { 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; const int index = (ny - y) + this->m_filtersize;
float value = finv_test(buffer[bufferindex], do_invert); float value = finv_test(buffer[bufferindex], do_invert);

View File

@@ -293,7 +293,7 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y,
int minyr = y - refrady < 0 ? -y : -refrady; int minyr = y - refrady < 0 ? -y : -refrady;
int maxyr = y + refrady > imgy ? imgy - 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_NO_CHANNELS_COLOR * ( (y + minyr) * imgx + x + minxr);
gausstabx = m_maintabs[refradx - 1]; gausstabx = m_maintabs[refradx - 1];
gausstabcentx = gausstabx + refradx; gausstabcentx = gausstabx + refradx;
@@ -301,9 +301,9 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y,
gausstabcenty = gausstaby + refrady; gausstabcenty = gausstaby + refrady;
sum = gval = rval = bval = aval = 0.0f; 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_NO_CHANNELS_COLOR * imgx) {
src = srcd; src = srcd;
for (j = minxr; j < maxxr; j++, src += COM_NUMBER_OF_CHANNELS) { for (j = minxr; j < maxxr; j++, src += COM_NO_CHANNELS_COLOR) {
val = gausstabcenty[i] * gausstabcentx[j]; val = gausstabcenty[i] * gausstabcentx[j];
sum += val; sum += val;

View File

@@ -49,7 +49,7 @@ MemoryBuffer *GlareBaseOperation::createMemoryBuffer(rcti *rect2)
rect.ymin = 0; rect.ymin = 0;
rect.xmax = getWidth(); rect.xmax = getWidth();
rect.ymax = getHeight(); rect.ymax = getHeight();
MemoryBuffer *result = new MemoryBuffer(NULL, &rect); MemoryBuffer *result = MemoryBuffer::create(COM_DT_COLOR, &rect);
float *data = result->getBuffer(); float *data = result->getBuffer();
this->generateGlare(data, tile, this->m_settings); this->generateGlare(data, tile, this->m_settings);
return result; return result;

View File

@@ -259,8 +259,8 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
float *kernelBuffer = in2->getBuffer(); float *kernelBuffer = in2->getBuffer();
float *imageBuffer = in1->getBuffer(); float *imageBuffer = in1->getBuffer();
MemoryBuffer *rdst = new MemoryBuffer(NULL, in1->getRect()); MemoryBuffer *rdst = MemoryBuffer::create(COM_DT_COLOR, in1->getRect());
memset(rdst->getBuffer(), 0, rdst->getWidth() * rdst->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); memset(rdst->getBuffer(), 0, rdst->getWidth() * rdst->getHeight() * COM_NO_CHANNELS_COLOR * sizeof(float));
// convolution result width & height // convolution result width & height
w2 = 2 * kernelWidth - 1; w2 = 2 * kernelWidth - 1;
@@ -276,7 +276,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
// normalize convolutor // normalize convolutor
wt[0] = wt[1] = wt[2] = 0.f; wt[0] = wt[1] = wt[2] = 0.f;
for (y = 0; y < kernelHeight; y++) { for (y = 0; y < kernelHeight; y++) {
colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS]; colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NO_CHANNELS_COLOR];
for (x = 0; x < kernelWidth; x++) for (x = 0; x < kernelWidth; x++)
add_v3_v3(wt, colp[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[1] != 0.f) wt[1] = 1.f / wt[1];
if (wt[2] != 0.f) wt[2] = 1.f / wt[2]; if (wt[2] != 0.f) wt[2] = 1.f / wt[2];
for (y = 0; y < kernelHeight; y++) { for (y = 0; y < kernelHeight; y++) {
colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS]; colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NO_CHANNELS_COLOR];
for (x = 0; x < kernelWidth; x++) for (x = 0; x < kernelWidth; x++)
mul_v3_v3(colp[x], wt); mul_v3_v3(colp[x], wt);
} }
@@ -313,7 +313,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
// in2, channel ch -> data1 // in2, channel ch -> data1
for (y = 0; y < kernelHeight; y++) { for (y = 0; y < kernelHeight; y++) {
fp = &data1ch[y * w2]; fp = &data1ch[y * w2];
colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS]; colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NO_CHANNELS_COLOR];
for (x = 0; x < kernelWidth; x++) for (x = 0; x < kernelWidth; x++)
fp[x] = colp[x][ch]; fp[x] = colp[x][ch];
} }
@@ -325,7 +325,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
int yy = ybl * ybsz + y; int yy = ybl * ybsz + y;
if (yy >= imageHeight) continue; if (yy >= imageHeight) continue;
fp = &data2[y * w2]; fp = &data2[y * w2];
colp = (fRGB *)&imageBuffer[yy * imageWidth * COM_NUMBER_OF_CHANNELS]; colp = (fRGB *)&imageBuffer[yy * imageWidth * COM_NO_CHANNELS_COLOR];
for (x = 0; x < xbsz; x++) { for (x = 0; x < xbsz; x++) {
int xx = xbl * xbsz + x; int xx = xbl * xbsz + x;
if (xx >= imageWidth) continue; if (xx >= imageWidth) continue;
@@ -349,7 +349,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
const int yy = ybl * ybsz + y - hh; const int yy = ybl * ybsz + y - hh;
if ((yy < 0) || (yy >= imageHeight)) continue; if ((yy < 0) || (yy >= imageHeight)) continue;
fp = &data2[y * w2]; fp = &data2[y * w2];
colp = (fRGB *)&rdst->getBuffer()[yy * imageWidth * COM_NUMBER_OF_CHANNELS]; colp = (fRGB *)&rdst->getBuffer()[yy * imageWidth * COM_NO_CHANNELS_COLOR];
for (x = 0; x < (int)w2; x++) { for (x = 0; x < (int)w2; x++) {
const int xx = xbl * xbsz + x - hw; const int xx = xbl * xbsz + x - hw;
if ((xx < 0) || (xx >= imageWidth)) continue; if ((xx < 0) || (xx >= imageWidth)) continue;
@@ -364,7 +364,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
MEM_freeN(data2); MEM_freeN(data2);
MEM_freeN(data1); MEM_freeN(data1);
memcpy(dst, rdst->getBuffer(), sizeof(float) * imageWidth * imageHeight * COM_NUMBER_OF_CHANNELS); memcpy(dst, rdst->getBuffer(), sizeof(float) * imageWidth * imageHeight * COM_NO_CHANNELS_COLOR);
delete(rdst); delete(rdst);
} }
@@ -381,7 +381,7 @@ void GlareFogGlowOperation::generateGlare(float *data, MemoryBuffer *inputTile,
// make the convolution kernel // make the convolution kernel
rcti kernelRect; rcti kernelRect;
BLI_rcti_init(&kernelRect, 0, sz, 0, sz); BLI_rcti_init(&kernelRect, 0, sz, 0, sz);
ckrn = new MemoryBuffer(NULL, &kernelRect); ckrn = MemoryBuffer::create(COM_DT_COLOR, &kernelRect);
scale = 0.25f * sqrtf((float)(sz * sz)); scale = 0.25f * sqrtf((float)(sz * sz));

View File

@@ -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_NO_CHANNELS_COLOR * sizeof(float));
for (n = 1; n < settings->iter && (!breaked); n++) { for (n = 1; n < settings->iter && (!breaked); n++) {
for (y = 0; y < gbuf->getHeight() && (!breaked); y++) { for (y = 0; y < gbuf->getHeight() && (!breaked); y++) {
v = ((float)y + 0.5f) / (float)gbuf->getHeight(); v = ((float)y + 0.5f) / (float)gbuf->getHeight();
@@ -117,9 +117,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No
} }
if (isBreaked()) breaked = true; 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_NO_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_NO_CHANNELS_COLOR * sizeof(float));
delete gbuf; delete gbuf;
delete tbuf1; delete tbuf1;

View File

@@ -36,7 +36,7 @@ void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile,
bool breaked = false; bool breaked = false;
MemoryBuffer *tsrc = inputTile->duplicate(); MemoryBuffer *tsrc = inputTile->duplicate();
MemoryBuffer *tdst = new MemoryBuffer(NULL, inputTile->getRect()); MemoryBuffer *tdst = MemoryBuffer::create(COM_DT_COLOR, inputTile->getRect());
tdst->clear(); tdst->clear();
memset(data, 0, size4 * sizeof(float)); memset(data, 0, size4 * sizeof(float));

View File

@@ -83,8 +83,8 @@ float *InpaintSimpleOperation::get_pixel(int x, int y)
ASSERT_XY_RANGE(x, y); ASSERT_XY_RANGE(x, y);
return &this->m_cached_buffer[ return &this->m_cached_buffer[
y * width * COM_NUMBER_OF_CHANNELS + y * width * COM_NO_CHANNELS_COLOR +
x * COM_NUMBER_OF_CHANNELS]; x * COM_NO_CHANNELS_COLOR];
} }
int InpaintSimpleOperation::mdist(int x, int y) int InpaintSimpleOperation::mdist(int x, int y)

View File

@@ -63,7 +63,7 @@ void KeyingBlurOperation::executePixel(float output[4], int x, int y, void *data
int cx = x + i; int cx = x + i;
if (cx >= 0 && cx < bufferWidth) { if (cx >= 0 && cx < bufferWidth) {
int bufferIndex = (y * bufferWidth + cx) * 4; int bufferIndex = (y * bufferWidth + cx);
average += buffer[bufferIndex]; average += buffer[bufferIndex];
count++; count++;
@@ -75,7 +75,7 @@ void KeyingBlurOperation::executePixel(float output[4], int x, int y, void *data
int cy = y + i; int cy = y + i;
if (cy >= 0 && cy < bufferHeight) { if (cy >= 0 && cy < bufferHeight) {
int bufferIndex = (cy * bufferWidth + x) * 4; int bufferIndex = (cy * bufferWidth + x);
average += buffer[bufferIndex]; average += buffer[bufferIndex];
count++; count++;

View File

@@ -64,7 +64,7 @@ void KeyingClipOperation::executePixel(float output[4], int x, int y, void *data
int i, j, count = 0, totalCount = 0; int i, j, count = 0, totalCount = 0;
float value = buffer[(y * bufferWidth + x) * 4]; float value = buffer[(y * bufferWidth + x)];
bool ok = false; bool ok = false;
@@ -76,7 +76,7 @@ void KeyingClipOperation::executePixel(float output[4], int x, int y, void *data
continue; continue;
if (cx >= 0 && cx < bufferWidth && cy >= 0 && cy < bufferHeight) { if (cx >= 0 && cx < bufferWidth && cy >= 0 && cy < bufferHeight) {
int bufferIndex = (cy * bufferWidth + cx) * 4; int bufferIndex = (cy * bufferWidth + cx);
float currentValue = buffer[bufferIndex]; float currentValue = buffer[bufferIndex];
if (fabsf(currentValue - value) < tolerance) { if (fabsf(currentValue - value) < tolerance) {

View File

@@ -77,17 +77,17 @@ bool MapUVOperation::read_uv(float x, float y, float &r_u, float &r_v, float &r_
float width = m_inputUVProgram->getWidth(); float width = m_inputUVProgram->getWidth();
float height = m_inputUVProgram->getHeight(); float height = m_inputUVProgram->getHeight();
if (x < 0.0f || x >= width || y < 0.0f || y >= height) { if (x < 0.0f || x >= width || y < 0.0f || y >= height) {
r_u = 0.0f; r_u = 0.0f;
r_v = 0.0f; r_v = 0.0f;
r_alpha = 0.0f; r_alpha = 0.0f;
return false; return false;
} }
else { else {
float col[4]; float vector[3];
m_inputUVProgram->readSampled(col, x, y, COM_PS_BILINEAR); m_inputUVProgram->readSampled(vector, x, y, COM_PS_BILINEAR);
r_u = col[0] * m_inputColorProgram->getWidth(); r_u = vector[0] * m_inputColorProgram->getWidth();
r_v = col[1] * m_inputColorProgram->getHeight(); r_v = vector[1] * m_inputColorProgram->getHeight();
r_alpha = col[2]; r_alpha = vector[2];
return true; return true;
} }
} }

View File

@@ -104,7 +104,7 @@ void *NormalizeOperation::initializeTileData(rcti *rect)
if ((value < minv) && (value >= -BLENDER_ZMAX)) { if ((value < minv) && (value >= -BLENDER_ZMAX)) {
minv = value; minv = value;
} }
bc += 4; bc += COM_NO_CHANNELS_VALUE;
} }
minmult->x = minv; minmult->x = minv;

View File

@@ -26,7 +26,7 @@ QualityStepHelper::QualityStepHelper()
{ {
this->m_quality = COM_QUALITY_HIGH; this->m_quality = COM_QUALITY_HIGH;
this->m_step = 1; this->m_step = 1;
this->m_offsetadd = 4; this->m_offsetadd = 4;
} }
void QualityStepHelper::initExecution(QualityHelper helper) void QualityStepHelper::initExecution(QualityHelper helper)
@@ -37,16 +37,16 @@ void QualityStepHelper::initExecution(QualityHelper helper)
case COM_QUALITY_HIGH: case COM_QUALITY_HIGH:
default: default:
this->m_step = 1; this->m_step = 1;
this->m_offsetadd = 4; this->m_offsetadd = 1;
break; break;
case COM_QUALITY_MEDIUM: case COM_QUALITY_MEDIUM:
this->m_step = 2; this->m_step = 2;
this->m_offsetadd = 8; this->m_offsetadd = 2;
break; break;
case COM_QUALITY_LOW: case COM_QUALITY_LOW:
this->m_step = 3; this->m_step = 3;
this->m_offsetadd = 12; this->m_offsetadd = 3;
break; break;
} }
break; break;
case COM_QH_MULTIPLY: case COM_QH_MULTIPLY:
@@ -54,16 +54,16 @@ void QualityStepHelper::initExecution(QualityHelper helper)
case COM_QUALITY_HIGH: case COM_QUALITY_HIGH:
default: default:
this->m_step = 1; this->m_step = 1;
this->m_offsetadd = 4; this->m_offsetadd = 4;
break; break;
case COM_QUALITY_MEDIUM: case COM_QUALITY_MEDIUM:
this->m_step = 2; this->m_step = 2;
this->m_offsetadd = 8; this->m_offsetadd = 8;
break; break;
case COM_QUALITY_LOW: case COM_QUALITY_LOW:
this->m_step = 4; this->m_step = 4;
this->m_offsetadd = 16; this->m_offsetadd = 16;
break; break;
} }
break; break;
} }

View File

@@ -24,9 +24,9 @@
#include "COM_WriteBufferOperation.h" #include "COM_WriteBufferOperation.h"
#include "COM_defines.h" #include "COM_defines.h"
ReadBufferOperation::ReadBufferOperation() : NodeOperation() ReadBufferOperation::ReadBufferOperation(DataType type) : NodeOperation()
{ {
this->addOutputSocket(COM_DT_COLOR); this->addOutputSocket(type);
this->m_single_value = false; this->m_single_value = false;
this->m_offset = 0; this->m_offset = 0;
this->m_buffer = NULL; this->m_buffer = NULL;

View File

@@ -33,7 +33,7 @@ private:
unsigned int m_offset; unsigned int m_offset;
MemoryBuffer *m_buffer; MemoryBuffer *m_buffer;
public: public:
ReadBufferOperation(); ReadBufferOperation(DataType type);
void setMemoryProxy(MemoryProxy *memoryProxy) { this->m_memoryProxy = memoryProxy; } void setMemoryProxy(MemoryProxy *memoryProxy) { this->m_memoryProxy = memoryProxy; }
MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; } MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; }
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);

View File

@@ -89,7 +89,6 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi
else else
zero_v4(output); zero_v4(output);
break; break;
} }
offset = (iy * width + ix) * this->m_elementsize; offset = (iy * width + ix) * this->m_elementsize;
@@ -111,15 +110,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); BLI_bicubic_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
break; 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) void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
@@ -148,7 +138,15 @@ void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y
#endif #endif
if (this->m_inputBuffer == NULL) { 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 {
zero_v4(output);
}
} }
else { else {
doInterpolation(output, ix, iy, sampler); doInterpolation(output, ix, iy, sampler);
@@ -210,16 +208,10 @@ void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, float
if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) { if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) {
output[0] = 0.0f; output[0] = 0.0f;
output[1] = 0.0f;
output[2] = 0.0f;
output[3] = 0.0f;
} }
else { else {
unsigned int offset = (iy * this->getWidth() + ix) * 4; unsigned int offset = (iy * this->getWidth() + ix) * 4;
output[0] = inputBuffer[offset + 3]; output[0] = inputBuffer[offset + 3];
output[1] = 0.0f;
output[2] = 0.0f;
output[3] = 0.0f;
} }
} }
@@ -252,16 +244,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() ) { if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) {
output[0] = 0.0f; output[0] = 0.0f;
output[1] = 0.0f;
output[2] = 0.0f;
output[3] = 0.0f;
} }
else { else {
unsigned int offset = (iy * this->getWidth() + ix); unsigned int offset = (iy * this->getWidth() + ix);
output[0] = inputBuffer[offset]; output[0] = inputBuffer[offset];
output[1] = 0.0f;
output[2] = 0.0f;
output[3] = 0.0f;
} }
} }

View File

@@ -33,7 +33,7 @@ void SetVectorOperation::executePixelSampled(float output[4], float x, float y,
output[0] = this->m_x; output[0] = this->m_x;
output[1] = this->m_y; output[1] = this->m_y;
output[2] = this->m_z; output[2] = this->m_z;
output[3] = this->m_w; // output[3] = this->m_w; not supported anymore?
} }
void SetVectorOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) void SetVectorOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])

View File

@@ -77,11 +77,9 @@ void TextureBaseOperation::determineResolution(unsigned int resolution[2], unsig
void TextureAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) void TextureAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{ {
TextureBaseOperation::executePixelSampled(output, x, y, sampler); float color[4];
output[0] = output[3]; TextureBaseOperation::executePixelSampled(color, x, y, sampler);
output[1] = 0.0f; output[0] = color[3];
output[2] = 0.0f;
output[3] = 0.0f;
} }
void TextureBaseOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) void TextureBaseOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
@@ -124,18 +122,23 @@ MemoryBuffer *TextureBaseOperation::createMemoryBuffer(rcti *rect2)
{ {
int height = getHeight(); int height = getHeight();
int width = getWidth(); int width = getWidth();
DataType datatype = this->getOutputSocket()->getDataType();
int add = 4;
if (datatype == COM_DT_VALUE) {
add = 1;
}
rcti rect; rcti rect;
rect.xmin = 0; rect.xmin = 0;
rect.ymin = 0; rect.ymin = 0;
rect.xmax = width; rect.xmax = width;
rect.ymax = height; rect.ymax = height;
MemoryBuffer *result = new MemoryBuffer(NULL, &rect); MemoryBuffer *result = MemoryBuffer::create(datatype, &rect);
float *data = result->getBuffer(); float *data = result->getBuffer();
for (int y = 0; y < height; y++) { 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); this->executePixelSampled(data, x, y, COM_PS_NEAREST);
} }
} }

View File

@@ -137,16 +137,19 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y,
copy_v4_fl(multiplier_accum, 1.0f); copy_v4_fl(multiplier_accum, 1.0f);
float size_center = tempSize[0] * scalar; 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_NO_CHANNELS_COLOR;
if (size_center > this->m_threshold) { 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; float dy = ny - y;
int offsetNy = ny * inputSizeBuffer->getWidth() * COM_NUMBER_OF_CHANNELS; int offsetValueNy = ny * inputSizeBuffer->getWidth();
int offsetNxNy = offsetNy + (minx * COM_NUMBER_OF_CHANNELS); int offsetValueNxNy = offsetValueNy + (minx);
for (int nx = minx; nx < maxx; nx += QualityStepHelper::getStep()) { int offsetColorNxNy = offsetValueNxNy * COM_NO_CHANNELS_COLOR;
for (int nx = minx; nx < maxx; nx += addXStepValue) {
if (nx != x || ny != y) { 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) { if (size > this->m_threshold) {
float dx = nx - x; float dx = nx - x;
if (size > fabsf(dx) && size > fabsf(dy)) { if (size > fabsf(dx) && size > fabsf(dy)) {
@@ -154,13 +157,14 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y,
(float)(COM_BLUR_BOKEH_PIXELS / 2) + (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1), (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)}; (float)(COM_BLUR_BOKEH_PIXELS / 2) + (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1)};
inputBokehBuffer->readNoCheck(bokeh, uv[0], uv[1]); inputBokehBuffer->readNoCheck(bokeh, uv[0], uv[1]);
madd_v4_v4v4(color_accum, bokeh, &inputProgramFloatBuffer[offsetNxNy]); madd_v4_v4v4(color_accum, bokeh, &inputProgramFloatBuffer[offsetColorNxNy]);
add_v4_v4(multiplier_accum, bokeh); add_v4_v4(multiplier_accum, bokeh);
} }
} }
} }
offsetNxNy += addXStep; offsetColorNxNy += addXStepColor;
} offsetValueNxNy += addXStepValue;
}
} }
} }
@@ -286,7 +290,7 @@ void InverseSearchRadiusOperation::initExecution()
voi *InverseSearchRadiusOperation::initializeTileData(rcti *rect) voi *InverseSearchRadiusOperation::initializeTileData(rcti *rect)
{ {
MemoryBuffer * data = new MemoryBuffer(NULL, rect); MemoryBuffer * data = MemoryBuffer::(NULL, rect);
float *buffer = data->getBuffer(); float *buffer = data->getBuffer();
int x, y; int x, y;
int width = this->m_inputRadius->getWidth(); int width = this->m_inputRadius->getWidth();

View File

@@ -57,7 +57,7 @@ void VectorBlurOperation::initExecution()
void VectorBlurOperation::executePixel(float output[4], int x, int y, void *data) void VectorBlurOperation::executePixel(float output[4], int x, int y, void *data)
{ {
float *buffer = (float *) data; float *buffer = (float *) data;
int index = (y * this->getWidth() + x) * COM_NUMBER_OF_CHANNELS; int index = (y * this->getWidth() + x) * COM_NO_CHANNELS_COLOR;
copy_v4_v4(output, &buffer[index]); copy_v4_v4(output, &buffer[index]);
} }
@@ -108,14 +108,12 @@ bool VectorBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBuff
void VectorBlurOperation::generateVectorBlur(float *data, MemoryBuffer *inputImage, MemoryBuffer *inputSpeed, MemoryBuffer *inputZ) void VectorBlurOperation::generateVectorBlur(float *data, MemoryBuffer *inputImage, MemoryBuffer *inputSpeed, MemoryBuffer *inputZ)
{ {
float *zbuf = inputZ->convertToValueBuffer();
NodeBlurData blurdata; NodeBlurData blurdata;
blurdata.samples = this->m_settings->samples / QualityStepHelper::getStep(); blurdata.samples = this->m_settings->samples / QualityStepHelper::getStep();
blurdata.maxspeed = this->m_settings->maxspeed; blurdata.maxspeed = this->m_settings->maxspeed;
blurdata.minspeed = this->m_settings->minspeed; blurdata.minspeed = this->m_settings->minspeed;
blurdata.curved = this->m_settings->curved; blurdata.curved = this->m_settings->curved;
blurdata.fac = this->m_settings->fac; blurdata.fac = this->m_settings->fac;
RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), zbuf); RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), inputZ->getBuffer());
MEM_freeN((void *)zbuf);
return; return;
} }

View File

@@ -51,7 +51,6 @@ void VectorCurveOperation::executePixelSampled(float output[4], float x, float y
this->m_inputProgram->readSampled(input, x, y, sampler); this->m_inputProgram->readSampled(input, x, y, sampler);
curvemapping_evaluate_premulRGBF(this->m_curveMapping, output, input); curvemapping_evaluate_premulRGBF(this->m_curveMapping, output, input);
output[3] = input[3];
} }
void VectorCurveOperation::deinitExecution() void VectorCurveOperation::deinitExecution()

View File

@@ -23,7 +23,7 @@
#include "COM_WrapOperation.h" #include "COM_WrapOperation.h"
WrapOperation::WrapOperation() : ReadBufferOperation() WrapOperation::WrapOperation(DataType type) : ReadBufferOperation(type)
{ {
this->m_wrappingType = CMP_NODE_WRAP_NONE; this->m_wrappingType = CMP_NODE_WRAP_NONE;
} }

View File

@@ -29,7 +29,7 @@ class WrapOperation : public ReadBufferOperation {
private: private:
int m_wrappingType; int m_wrappingType;
public: public:
WrapOperation(); WrapOperation(DataType type);
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);

View File

@@ -25,10 +25,10 @@
#include <stdio.h> #include <stdio.h>
#include "COM_OpenCLDevice.h" #include "COM_OpenCLDevice.h"
WriteBufferOperation::WriteBufferOperation() : NodeOperation() WriteBufferOperation::WriteBufferOperation(DataType type) : NodeOperation()
{ {
this->addInputSocket(COM_DT_COLOR); this->addInputSocket(type);
this->m_memoryProxy = new MemoryProxy(); this->m_memoryProxy = new MemoryProxy(type);
this->m_memoryProxy->setWriteBufferOperation(this); this->m_memoryProxy->setWriteBufferOperation(this);
this->m_memoryProxy->setExecutor(NULL); this->m_memoryProxy->setExecutor(NULL);
} }
@@ -61,6 +61,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
{ {
MemoryBuffer *memoryBuffer = this->m_memoryProxy->getBuffer(); MemoryBuffer *memoryBuffer = this->m_memoryProxy->getBuffer();
float *buffer = memoryBuffer->getBuffer(); float *buffer = memoryBuffer->getBuffer();
const int no_channels = memoryBuffer->get_no_channels();
if (this->m_input->isComplex()) { if (this->m_input->isComplex()) {
void *data = this->m_input->initializeTileData(rect); void *data = this->m_input->initializeTileData(rect);
int x1 = rect->xmin; int x1 = rect->xmin;
@@ -71,10 +72,10 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int y; int y;
bool breaked = false; bool breaked = false;
for (y = y1; y < y2 && (!breaked); y++) { for (y = y1; y < y2 && (!breaked); y++) {
int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS; int offset4 = (y * memoryBuffer->getWidth() + x1) * no_channels;
for (x = x1; x < x2; x++) { for (x = x1; x < x2; x++) {
this->m_input->read(&(buffer[offset4]), x, y, data); this->m_input->read(&(buffer[offset4]), x, y, data);
offset4 += COM_NUMBER_OF_CHANNELS; offset4 += no_channels;
} }
if (isBreaked()) { if (isBreaked()) {
breaked = true; breaked = true;
@@ -96,10 +97,10 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int y; int y;
bool breaked = false; bool breaked = false;
for (y = y1; y < y2 && (!breaked); y++) { for (y = y1; y < y2 && (!breaked); y++) {
int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS; int offset4 = (y * memoryBuffer->getWidth() + x1) * no_channels;
for (x = x1; x < x2; x++) { for (x = x1; x < x2; x++) {
this->m_input->readSampled(&(buffer[offset4]), x, y, COM_PS_NEAREST); this->m_input->readSampled(&(buffer[offset4]), x, y, COM_PS_NEAREST);
offset4 += COM_NUMBER_OF_CHANNELS; offset4 += no_channels;
} }
if (isBreaked()) { if (isBreaked()) {
breaked = true; breaked = true;
@@ -126,12 +127,9 @@ void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti *rect,
const unsigned int outputBufferWidth = outputBuffer->getWidth(); const unsigned int outputBufferWidth = outputBuffer->getWidth();
const unsigned int outputBufferHeight = outputBuffer->getHeight(); const unsigned int outputBufferHeight = outputBuffer->getHeight();
const cl_image_format imageFormat = { const cl_image_format *imageFormat = device->determineImageFormat(outputBuffer);
CL_RGBA,
CL_FLOAT
};
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)); } if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
// STEP 2 // STEP 2

View File

@@ -35,7 +35,7 @@ class WriteBufferOperation : public NodeOperation {
bool m_single_value; /* single value stored in buffer */ bool m_single_value; /* single value stored in buffer */
NodeOperation *m_input; NodeOperation *m_input;
public: public:
WriteBufferOperation(); WriteBufferOperation(DataType type);
~WriteBufferOperation(); ~WriteBufferOperation();
MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; } MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; }
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);