ensureSizeIsEnough now doesn't reallocate memory, if buffer is small submat of big matrix
fixed createContinous according new changes
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)
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
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