Commit afff9cf7 authored by Vladislav Vinogradov's avatar Vladislav Vinogradov

Optimized buffers reuse in gpu module:

ensureSizeIsEnough now doesn't reallocate memory, if buffer is small submat of big matrix
fixed createContinous according new changes
parent 810829f3
......@@ -545,22 +545,6 @@ namespace cv { namespace gpu
ensureSizeIsEnough(size.height, size.width, type, m);
}
inline void createContinuous(int rows, int cols, int type, GpuMat& m)
{
int area = rows * cols;
if (!m.isContinuous() || m.type() != type || m.size().area() != area)
ensureSizeIsEnough(1, area, type, m);
m = m.reshape(0, rows);
}
inline void ensureSizeIsEnough(int rows, int cols, int type, GpuMat& m)
{
if (m.type() == type && m.rows >= rows && m.cols >= cols)
m = m(Rect(0, 0, cols, rows));
else
m.create(rows, cols, type);
}
inline GpuMat allocMatFromBuf(int rows, int cols, int type, GpuMat &mat)
{
if (!mat.empty() && mat.type() == type && mat.rows >= rows && mat.cols >= cols)
......
......@@ -704,6 +704,43 @@ cv::Mat::Mat(const GpuMat& m) : flags(0), dims(0), rows(0), cols(0), data(0), re
m.download(*this);
}
void cv::gpu::createContinuous(int rows, int cols, int type, GpuMat& m)
{
int area = rows * cols;
if (m.empty() || m.type() != type || !m.isContinuous() || m.size().area() < area)
m.create(1, area, type);
m.cols = cols;
m.rows = rows;
m.step = m.elemSize() * cols;
m.flags |= Mat::CONTINUOUS_FLAG;
}
void cv::gpu::ensureSizeIsEnough(int rows, int cols, int type, GpuMat& m)
{
if (m.empty() || m.type() != type || m.data != m.datastart)
m.create(rows, cols, type);
else
{
const size_t esz = m.elemSize();
const ptrdiff_t delta2 = m.dataend - m.datastart;
const size_t minstep = m.cols * esz;
Size wholeSize;
wholeSize.height = std::max(static_cast<int>((delta2 - minstep) / m.step + 1), m.rows);
wholeSize.width = std::max(static_cast<int>((delta2 - m.step * (wholeSize.height - 1)) / esz), m.cols);
if (wholeSize.height < rows || wholeSize.width < cols)
m.create(rows, cols, type);
else
{
m.cols = cols;
m.rows = rows;
}
}
}
namespace
{
class GpuFuncTable
......
......@@ -324,6 +324,40 @@ INSTANTIATE_TEST_CASE_P(GPU_GpuMat, ConvertTo, testing::Combine(
ALL_DEPTH,
WHOLE_SUBMAT));
////////////////////////////////////////////////////////////////////////////////
// ensureSizeIsEnough
struct EnsureSizeIsEnough : testing::TestWithParam<cv::gpu::DeviceInfo>
{
virtual void SetUp()
{
cv::gpu::DeviceInfo devInfo = GetParam();
cv::gpu::setDevice(devInfo.deviceID());
}
};
TEST_P(EnsureSizeIsEnough, BufferReuse)
{
cv::gpu::GpuMat buffer(100, 100, CV_8U);
cv::gpu::GpuMat old = buffer;
// don't reallocate memory
cv::gpu::ensureSizeIsEnough(10, 20, CV_8U, buffer);
EXPECT_EQ(10, buffer.rows);
EXPECT_EQ(20, buffer.cols);
EXPECT_EQ(CV_8UC1, buffer.type());
EXPECT_EQ(reinterpret_cast<intptr_t>(old.data), reinterpret_cast<intptr_t>(buffer.data));
// don't reallocate memory
cv::gpu::ensureSizeIsEnough(20, 30, CV_8U, buffer);
EXPECT_EQ(20, buffer.rows);
EXPECT_EQ(30, buffer.cols);
EXPECT_EQ(CV_8UC1, buffer.type());
EXPECT_EQ(reinterpret_cast<intptr_t>(old.data), reinterpret_cast<intptr_t>(buffer.data));
}
INSTANTIATE_TEST_CASE_P(GPU_GpuMat, EnsureSizeIsEnough, ALL_DEVICES);
} // namespace
#endif // HAVE_CUDA
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment