diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2015-01-19 20:13:26 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2015-01-19 20:17:50 +0300 |
commit | 35d3b6316b21ad9ae7eb96a7a541c4051eae3441 (patch) | |
tree | dd4eea63f9229d87041e2f5a5679d05f1360afea /source/blender/compositor/intern/COM_MemoryBuffer.cpp | |
parent | a8fa291b8c539da7669463ef622d5c61ee9c90e7 (diff) |
D627: Memory usage optimization for the compositor.
The compostor used a fixed size of 4 floats to hold pixel data. this
patch will select size of a pixel based on its type.
It uses 1 float for Value, 3 float for vector and 4 floats for color
data types.
When benchmarking on shots (opening shot of caminandes) we get a
reduction of memory of 30% and a tiny speedup as less data
transformations needs to take place (but these are negligable.
More information of the patch can be found on
https://developer.blender.org/D627 and
http://wiki.blender.org/index.php/Dev:Ref/Proposals/Compositor2014_p1.1_TD
Developers: jbakker & mdewanchand
Thanks for Sergey for his indept review.
Diffstat (limited to 'source/blender/compositor/intern/COM_MemoryBuffer.cpp')
-rw-r--r-- | source/blender/compositor/intern/COM_MemoryBuffer.cpp | 91 |
1 files changed, 54 insertions, 37 deletions
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp index c59ecced93c..58767960cc8 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp @@ -27,6 +27,18 @@ using std::min; using std::max; +static unsigned int determine_num_channels(DataType datatype) { + switch (datatype) { + case COM_DT_VALUE: + return COM_NUM_CHANNELS_VALUE; + case COM_DT_VECTOR: + return COM_NUM_CHANNELS_VECTOR; + case COM_DT_COLOR: + default: + return COM_NUM_CHANNELS_COLOR; + } +} + unsigned int MemoryBuffer::determineBufferSize() { return getWidth() * getHeight(); @@ -34,61 +46,62 @@ unsigned int MemoryBuffer::determineBufferSize() int MemoryBuffer::getWidth() const { - return this->m_rect.xmax - this->m_rect.xmin; + return this->m_width; } int MemoryBuffer::getHeight() const { - return this->m_rect.ymax - this->m_rect.ymin; + return this->m_height; } MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect) { BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax); + this->m_width = BLI_rcti_size_x(&this->m_rect); + this->m_height = BLI_rcti_size_y(&this->m_rect); this->m_memoryProxy = memoryProxy; this->m_chunkNumber = chunkNumber; - this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, 16, "COM_MemoryBuffer"); + this->m_num_channels = determine_num_channels(memoryProxy->getDataType()); + this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * this->m_num_channels, 16, "COM_MemoryBuffer"); this->m_state = COM_MB_ALLOCATED; - this->m_datatype = COM_DT_COLOR; - this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin; + this->m_datatype = memoryProxy->getDataType();; } MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect) { BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax); + this->m_width = BLI_rcti_size_x(&this->m_rect); + this->m_height = BLI_rcti_size_y(&this->m_rect); this->m_memoryProxy = memoryProxy; this->m_chunkNumber = -1; - this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, 16, "COM_MemoryBuffer"); + this->m_num_channels = determine_num_channels(memoryProxy->getDataType()); + this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * this->m_num_channels, 16, "COM_MemoryBuffer"); + this->m_state = COM_MB_TEMPORARILY; + this->m_datatype = memoryProxy->getDataType(); +} +MemoryBuffer::MemoryBuffer(DataType dataType, rcti *rect) +{ + BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax); + this->m_width = BLI_rcti_size_x(&this->m_rect); + this->m_height = BLI_rcti_size_y(&this->m_rect); + this->m_height = this->m_rect.ymax - this->m_rect.ymin; + this->m_memoryProxy = NULL; + this->m_chunkNumber = -1; + this->m_num_channels = determine_num_channels(dataType); + this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * this->m_num_channels, 16, "COM_MemoryBuffer"); this->m_state = COM_MB_TEMPORARILY; - this->m_datatype = COM_DT_COLOR; - this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin; + this->m_datatype = dataType; } MemoryBuffer *MemoryBuffer::duplicate() { MemoryBuffer *result = new MemoryBuffer(this->m_memoryProxy, &this->m_rect); - memcpy(result->m_buffer, this->m_buffer, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float)); + memcpy(result->m_buffer, this->m_buffer, this->determineBufferSize() * this->m_num_channels * sizeof(float)); return result; } void MemoryBuffer::clear() { - memset(this->m_buffer, 0, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float)); + memset(this->m_buffer, 0, this->determineBufferSize() * this->m_num_channels * sizeof(float)); } -float *MemoryBuffer::convertToValueBuffer() -{ - const unsigned int size = this->determineBufferSize(); - unsigned int i; - - float *result = (float *)MEM_mallocN(sizeof(float) * size, __func__); - - const float *fp_src = this->m_buffer; - float *fp_dst = result; - - for (i = 0; i < size; i++, fp_dst++, fp_src += COM_NUMBER_OF_CHANNELS) { - *fp_dst = *fp_src; - } - - return result; -} float MemoryBuffer::getMaximumValue() { @@ -98,7 +111,7 @@ float MemoryBuffer::getMaximumValue() const float *fp_src = this->m_buffer; - for (i = 0; i < size; i++, fp_src += COM_NUMBER_OF_CHANNELS) { + for (i = 0; i < size; i++, fp_src += this->m_num_channels) { float value = *fp_src; if (value > result) { result = value; @@ -116,7 +129,7 @@ float MemoryBuffer::getMaximumValue(rcti *rect) BLI_rcti_isect(rect, &this->m_rect, &rect_clamp); if (!BLI_rcti_is_empty(&rect_clamp)) { - MemoryBuffer *temp = new MemoryBuffer(NULL, &rect_clamp); + MemoryBuffer *temp = new MemoryBuffer(this->m_datatype, &rect_clamp); temp->copyContentFrom(this); float result = temp->getMaximumValue(); delete temp; @@ -152,9 +165,9 @@ void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer) for (otherY = minY; otherY < maxY; otherY++) { - otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_chunkWidth + minX - otherBuffer->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; - offset = ((otherY - this->m_rect.ymin) * this->m_chunkWidth + minX - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; - memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * COM_NUMBER_OF_CHANNELS * sizeof(float)); + otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_width + minX - otherBuffer->m_rect.xmin) * this->m_num_channels; + offset = ((otherY - this->m_rect.ymin) * this->m_width + minX - this->m_rect.xmin) * this->m_num_channels; + memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * this->m_num_channels * sizeof(float)); } } @@ -163,9 +176,8 @@ void MemoryBuffer::writePixel(int x, int y, const float color[4]) if (x >= this->m_rect.xmin && x < this->m_rect.xmax && y >= this->m_rect.ymin && y < this->m_rect.ymax) { - const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; - copy_v4_v4(&this->m_buffer[offset], color); - } + const int offset = (this->m_width * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * this->m_num_channels; + memcpy(&this->m_buffer[offset], color, sizeof(float)*this->m_num_channels); } } void MemoryBuffer::addPixel(int x, int y, const float color[4]) @@ -173,8 +185,12 @@ void MemoryBuffer::addPixel(int x, int y, const float color[4]) if (x >= this->m_rect.xmin && x < this->m_rect.xmax && y >= this->m_rect.ymin && y < this->m_rect.ymax) { - const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; - add_v4_v4(&this->m_buffer[offset], color); + const int offset = (this->m_width * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * this->m_num_channels; + float *dst = &this->m_buffer[offset]; + const float *src = color; + for (int i = 0; i < this->m_num_channels ; i++, dst++, src++) { + *dst += *src; + } } } @@ -208,8 +224,9 @@ static void read_ewa_pixel_sampled(void *userdata, int x, int y, float result[4] } } -void MemoryBuffer::readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler) +void MemoryBuffer::readEWA(float *result, const float uv[2], const float derivatives[2][2], PixelSampler sampler) { + BLI_assert(this->m_datatype==COM_DT_COLOR); ReadEWAData data; data.buffer = this; data.sampler = sampler; |