From: Vladislav Vinogradov Date: Fri, 26 Oct 2012 11:49:39 +0000 (+0400) Subject: Optimized buffers reuse in gpu module: X-Git-Tag: accepted/tizen/6.0/unified/20201030.111113~4052^2~61 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=afff9cf71634a96a491fdc7d195e267ba126871e;p=platform%2Fupstream%2Fopencv.git 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 --- diff --git a/modules/core/include/opencv2/core/gpumat.hpp b/modules/core/include/opencv2/core/gpumat.hpp index 2830a9e..73da7e7 100644 --- a/modules/core/include/opencv2/core/gpumat.hpp +++ b/modules/core/include/opencv2/core/gpumat.hpp @@ -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) diff --git a/modules/core/src/gpumat.cpp b/modules/core/src/gpumat.cpp index fc291a8..afd7115 100644 --- a/modules/core/src/gpumat.cpp +++ b/modules/core/src/gpumat.cpp @@ -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((delta2 - minstep) / m.step + 1), m.rows); + wholeSize.width = std::max(static_cast((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 diff --git a/modules/gpu/test/test_gpumat.cpp b/modules/gpu/test/test_gpumat.cpp index 7a4a616..9d7e545 100644 --- a/modules/gpu/test/test_gpumat.cpp +++ b/modules/gpu/test/test_gpumat.cpp @@ -324,6 +324,40 @@ INSTANTIATE_TEST_CASE_P(GPU_GpuMat, ConvertTo, testing::Combine( ALL_DEPTH, WHOLE_SUBMAT)); +//////////////////////////////////////////////////////////////////////////////// +// ensureSizeIsEnough + +struct EnsureSizeIsEnough : testing::TestWithParam +{ + 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(old.data), reinterpret_cast(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(old.data), reinterpret_cast(buffer.data)); +} + +INSTANTIATE_TEST_CASE_P(GPU_GpuMat, EnsureSizeIsEnough, ALL_DEVICES); + } // namespace #endif // HAVE_CUDA