From: Vladislav Vinogradov Date: Mon, 15 Apr 2013 10:17:18 +0000 (+0400) Subject: added Stream support to ogl::Buffer X-Git-Tag: accepted/tizen/6.0/unified/20201030.111113~3878^2~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6994a02c152f4989c07b7204a02e29d1d4a5a000;p=platform%2Fupstream%2Fopencv.git added Stream support to ogl::Buffer --- diff --git a/modules/core/include/opencv2/core/opengl.hpp b/modules/core/include/opencv2/core/opengl.hpp index a7a7ae5..a4ee091 100644 --- a/modules/core/include/opencv2/core/opengl.hpp +++ b/modules/core/include/opencv2/core/opengl.hpp @@ -40,8 +40,12 @@ // //M*/ -#ifndef __OPENCV_OPENGL_INTEROP_HPP__ -#define __OPENCV_OPENGL_INTEROP_HPP__ +#ifndef __OPENCV_CORE_OPENGL_HPP__ +#define __OPENCV_CORE_OPENGL_HPP__ + +#ifndef __cplusplus +# error opengl.hpp header must be compiled as C++ +#endif #include "opencv2/core.hpp" @@ -84,7 +88,7 @@ public: //! create buffer void create(int arows, int acols, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false); - void create(Size asize, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false) { create(asize.height, asize.width, atype, target, autoRelease); } + void create(Size asize, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false); //! release memory and delete buffer object void release(); @@ -92,11 +96,15 @@ public: //! set auto release mode (if true, release will be called in object's destructor) void setAutoRelease(bool flag); - //! copy from host/device memory + //! copy from host/device memory (blocking) void copyFrom(InputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false); + //! copy from device memory (non blocking) + void copyFrom(InputArray arr, gpu::Stream& stream, Target target = ARRAY_BUFFER, bool autoRelease = false); - //! copy to host/device memory - void copyTo(OutputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false) const; + //! copy to host/device memory (blocking) + void copyTo(OutputArray arr) const; + //! copy to device memory (non blocking) + void copyTo(OutputArray arr, gpu::Stream& stream) const; //! create copy of current buffer Buffer clone(Target target = ARRAY_BUFFER, bool autoRelease = false) const; @@ -111,21 +119,26 @@ public: Mat mapHost(Access access); void unmapHost(); - //! map to device memory + //! map to device memory (blocking) gpu::GpuMat mapDevice(); void unmapDevice(); - int rows() const { return rows_; } - int cols() const { return cols_; } - Size size() const { return Size(cols_, rows_); } - bool empty() const { return rows_ == 0 || cols_ == 0; } + //! map to device memory (non blocking) + gpu::GpuMat mapDevice(gpu::Stream& stream); + void unmapDevice(gpu::Stream& stream); - int type() const { return type_; } - int depth() const { return CV_MAT_DEPTH(type_); } - int channels() const { return CV_MAT_CN(type_); } - int elemSize() const { return CV_ELEM_SIZE(type_); } - int elemSize1() const { return CV_ELEM_SIZE1(type_); } + int rows() const; + int cols() const; + Size size() const; + bool empty() const; + int type() const; + int depth() const; + int channels() const; + int elemSize() const; + int elemSize1() const; + + //! get OpenGL opject id unsigned int bufId() const; class Impl; @@ -165,7 +178,7 @@ public: //! create texture void create(int arows, int acols, Format aformat, bool autoRelease = false); - void create(Size asize, Format aformat, bool autoRelease = false) { create(asize.height, asize.width, aformat, autoRelease); } + void create(Size asize, Format aformat, bool autoRelease = false); //! release memory and delete texture object void release(); @@ -182,13 +195,14 @@ public: //! bind texture to current active texture unit for GL_TEXTURE_2D target void bind() const; - int rows() const { return rows_; } - int cols() const { return cols_; } - Size size() const { return Size(cols_, rows_); } - bool empty() const { return rows_ == 0 || cols_ == 0; } + int rows() const; + int cols() const; + Size size() const; + bool empty() const; - Format format() const { return format_; } + Format format() const; + //! get OpenGL opject id unsigned int texId() const; class Impl; @@ -224,8 +238,8 @@ public: void bind() const; - int size() const { return size_; } - bool empty() const { return size_ == 0; } + int size() const; + bool empty() const; private: int size_; @@ -260,14 +274,14 @@ enum { CV_EXPORTS void render(const Arrays& arr, int mode = POINTS, Scalar color = Scalar::all(255)); CV_EXPORTS void render(const Arrays& arr, InputArray indices, int mode = POINTS, Scalar color = Scalar::all(255)); -}} // namespace cv::gl +}} // namespace cv::ogl namespace cv { namespace gpu { //! set a CUDA device to use OpenGL interoperability CV_EXPORTS void setGlDevice(int device = 0); -}} // cv::gpu +}} namespace cv { @@ -276,4 +290,149 @@ template <> CV_EXPORTS void Ptr::delete_obj(); } -#endif // __OPENCV_OPENGL_INTEROP_HPP__ +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +inline +cv::ogl::Buffer::Buffer(int arows, int acols, int atype, Target target, bool autoRelease) : rows_(0), cols_(0), type_(0) +{ + create(arows, acols, atype, target, autoRelease); +} + +inline +cv::ogl::Buffer::Buffer(Size asize, int atype, Target target, bool autoRelease) : rows_(0), cols_(0), type_(0) +{ + create(asize, atype, target, autoRelease); +} + +inline +void cv::ogl::Buffer::create(Size asize, int atype, Target target, bool autoRelease) +{ + create(asize.height, asize.width, atype, target, autoRelease); +} + +inline +int cv::ogl::Buffer::rows() const +{ + return rows_; +} + +inline +int cv::ogl::Buffer::cols() const +{ + return cols_; +} + +inline +cv::Size cv::ogl::Buffer::size() const +{ + return Size(cols_, rows_); +} + +inline +bool cv::ogl::Buffer::empty() const +{ + return rows_ == 0 || cols_ == 0; +} + +inline +int cv::ogl::Buffer::type() const +{ + return type_; +} + +inline +int cv::ogl::Buffer::depth() const +{ + return CV_MAT_DEPTH(type_); +} + +inline +int cv::ogl::Buffer::channels() const +{ + return CV_MAT_CN(type_); +} + +inline +int cv::ogl::Buffer::elemSize() const +{ + return CV_ELEM_SIZE(type_); +} + +inline +int cv::ogl::Buffer::elemSize1() const +{ + return CV_ELEM_SIZE1(type_); +} + +/////// + +inline +cv::ogl::Texture2D::Texture2D(int arows, int acols, Format aformat, bool autoRelease) : rows_(0), cols_(0), format_(NONE) +{ + create(arows, acols, aformat, autoRelease); +} + +inline +cv::ogl::Texture2D::Texture2D(Size asize, Format aformat, bool autoRelease) : rows_(0), cols_(0), format_(NONE) +{ + create(asize, aformat, autoRelease); +} + +inline +void cv::ogl::Texture2D::create(Size asize, Format aformat, bool autoRelease) +{ + create(asize.height, asize.width, aformat, autoRelease); +} + +inline +int cv::ogl::Texture2D::rows() const +{ + return rows_; +} + +inline +int cv::ogl::Texture2D::cols() const +{ + return cols_; +} + +inline +cv::Size cv::ogl::Texture2D::size() const +{ + return Size(cols_, rows_); +} + +inline +bool cv::ogl::Texture2D::empty() const +{ + return rows_ == 0 || cols_ == 0; +} + +inline +cv::ogl::Texture2D::Format cv::ogl::Texture2D::format() const +{ + return format_; +} + +/////// + +inline +cv::ogl::Arrays::Arrays() : size_(0) +{ +} + +inline +int cv::ogl::Arrays::size() const +{ + return size_; +} + +inline +bool cv::ogl::Arrays::empty() const +{ + return size_ == 0; +} + +#endif /* __OPENCV_CORE_OPENGL_HPP__ */ diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 393798c..2f3e002 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -41,8 +41,6 @@ //M*/ #include "precomp.hpp" -#include "opencv2/core/gpu.hpp" -#include "opencv2/core/opengl.hpp" /****************************************************************************************\ * [scaled] Identity matrix initialization * diff --git a/modules/core/src/opengl.cpp b/modules/core/src/opengl.cpp index 1a10cc3..f8a647e 100644 --- a/modules/core/src/opengl.cpp +++ b/modules/core/src/opengl.cpp @@ -55,62 +55,61 @@ using namespace cv::gpu; namespace { #ifndef HAVE_OPENGL - void throw_no_ogl() { CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); } + inline void throw_no_ogl() { CV_Error(cv::Error::OpenGlNotSupported, "The library is compiled without OpenGL support"); } #else - void throw_no_ogl() { CV_Error(CV_OpenGlApiCallError, "OpenGL context doesn't exist"); } + inline void throw_no_ogl() { CV_Error(cv::Error::OpenGlApiCallError, "OpenGL context doesn't exist"); } #endif -bool checkError(const char* file, const int line, const char* func = 0) -{ -#ifndef HAVE_OPENGL - (void) file; - (void) line; - (void) func; - return true; -#else - GLenum err = gl::GetError(); - - if (err != gl::NO_ERROR_) + bool checkError(const char* file, const int line, const char* func = 0) { - const char* msg; + #ifndef HAVE_OPENGL + (void) file; + (void) line; + (void) func; + return true; + #else + GLenum err = gl::GetError(); - switch (err) + if (err != gl::NO_ERROR_) { - case gl::INVALID_ENUM: - msg = "An unacceptable value is specified for an enumerated argument"; - break; + const char* msg; - case gl::INVALID_VALUE: - msg = "A numeric argument is out of range"; - break; + switch (err) + { + case gl::INVALID_ENUM: + msg = "An unacceptable value is specified for an enumerated argument"; + break; - case gl::INVALID_OPERATION: - msg = "The specified operation is not allowed in the current state"; - break; + case gl::INVALID_VALUE: + msg = "A numeric argument is out of range"; + break; - case gl::OUT_OF_MEMORY: - msg = "There is not enough memory left to execute the command"; - break; + case gl::INVALID_OPERATION: + msg = "The specified operation is not allowed in the current state"; + break; - default: - msg = "Unknown error"; - }; + case gl::OUT_OF_MEMORY: + msg = "There is not enough memory left to execute the command"; + break; - cvError(CV_OpenGlApiCallError, func, msg, file, line); + default: + msg = "Unknown error"; + }; - return false; - } + cvError(CV_OpenGlApiCallError, func, msg, file, line); - return true; -#endif -} + return false; + } -#if defined(__GNUC__) - #define CV_CheckGlError() CV_DbgAssert( (checkError(__FILE__, __LINE__, __func__)) ) -#else - #define CV_CheckGlError() CV_DbgAssert( (checkError(__FILE__, __LINE__)) ) -#endif + return true; + #endif + } + #if defined(__GNUC__) + #define CV_CheckGlError() CV_DbgAssert( (checkError(__FILE__, __LINE__, __func__)) ) + #else + #define CV_CheckGlError() CV_DbgAssert( (checkError(__FILE__, __LINE__)) ) + #endif } // namespace #ifdef HAVE_OPENGL @@ -129,7 +128,7 @@ void cv::gpu::setGlDevice(int device) (void) device; throw_no_ogl(); #else - #if !defined(HAVE_CUDA) || defined(CUDA_DISABLER) + #ifndef HAVE_CUDA (void) device; throw_no_cuda(); #else @@ -141,7 +140,7 @@ void cv::gpu::setGlDevice(int device) //////////////////////////////////////////////////////////////////////// // CudaResource -#if defined(HAVE_OPENGL) && defined(HAVE_CUDA) && !defined(CUDA_DISABLER) +#if defined(HAVE_OPENGL) && defined(HAVE_CUDA) namespace { @@ -353,12 +352,13 @@ const Ptr& cv::ogl::Buffer::Impl::empty() return p; } -cv::ogl::Buffer::Impl::Impl() : bufId_(0), autoRelease_(true) +cv::ogl::Buffer::Impl::Impl() : bufId_(0), autoRelease_(false) { } cv::ogl::Buffer::Impl::Impl(GLuint abufId, bool autoRelease) : bufId_(abufId), autoRelease_(autoRelease) { + CV_Assert( gl::IsBuffer(abufId) == gl::TRUE_ ); } cv::ogl::Buffer::Impl::Impl(GLsizeiptr size, const GLvoid* data, GLenum target, bool autoRelease) : bufId_(0), autoRelease_(autoRelease) @@ -437,29 +437,31 @@ void cv::ogl::Buffer::Impl::unmapHost() } #ifdef HAVE_CUDA - void cv::ogl::Buffer::Impl::copyFrom(const void* src, size_t spitch, size_t width, size_t height, cudaStream_t stream) - { - cudaResource_.registerBuffer(bufId_); - cudaResource_.copyFrom(src, spitch, width, height, stream); - } - void cv::ogl::Buffer::Impl::copyTo(void* dst, size_t dpitch, size_t width, size_t height, cudaStream_t stream) const - { - cudaResource_.registerBuffer(bufId_); - cudaResource_.copyTo(dst, dpitch, width, height, stream); - } +void cv::ogl::Buffer::Impl::copyFrom(const void* src, size_t spitch, size_t width, size_t height, cudaStream_t stream) +{ + cudaResource_.registerBuffer(bufId_); + cudaResource_.copyFrom(src, spitch, width, height, stream); +} - void* cv::ogl::Buffer::Impl::mapDevice(cudaStream_t stream) - { - cudaResource_.registerBuffer(bufId_); - return cudaResource_.map(stream); - } +void cv::ogl::Buffer::Impl::copyTo(void* dst, size_t dpitch, size_t width, size_t height, cudaStream_t stream) const +{ + cudaResource_.registerBuffer(bufId_); + cudaResource_.copyTo(dst, dpitch, width, height, stream); +} - void cv::ogl::Buffer::Impl::unmapDevice(cudaStream_t stream) - { - cudaResource_.unmap(stream); - } -#endif +void* cv::ogl::Buffer::Impl::mapDevice(cudaStream_t stream) +{ + cudaResource_.registerBuffer(bufId_); + return cudaResource_.map(stream); +} + +void cv::ogl::Buffer::Impl::unmapDevice(cudaStream_t stream) +{ + cudaResource_.unmap(stream); +} + +#endif // HAVE_CUDA #endif // HAVE_OPENGL @@ -505,16 +507,6 @@ cv::ogl::Buffer::Buffer(Size asize, int atype, unsigned int abufId, bool autoRel #endif } -cv::ogl::Buffer::Buffer(int arows, int acols, int atype, Target target, bool autoRelease) : rows_(0), cols_(0), type_(0) -{ - create(arows, acols, atype, target, autoRelease); -} - -cv::ogl::Buffer::Buffer(Size asize, int atype, Target target, bool autoRelease) : rows_(0), cols_(0), type_(0) -{ - create(asize, atype, target, autoRelease); -} - cv::ogl::Buffer::Buffer(InputArray arr, Target target, bool autoRelease) : rows_(0), cols_(0), type_(0) { #ifndef HAVE_OPENGL @@ -528,16 +520,9 @@ cv::ogl::Buffer::Buffer(InputArray arr, Target target, bool autoRelease) : rows_ switch (kind) { case _InputArray::OPENGL_BUFFER: - { - copyFrom(arr, target, autoRelease); - break; - } - case _InputArray::GPU_MAT: - { - copyFrom(arr, target, autoRelease); - break; - } + copyFrom(arr, target, autoRelease); + break; default: { @@ -622,7 +607,7 @@ void cv::ogl::Buffer::copyFrom(InputArray arr, Target target, bool autoRelease) case _InputArray::GPU_MAT: { - #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + #ifndef HAVE_CUDA throw_no_cuda(); #else GpuMat dmat = arr.getGpuMat(); @@ -642,27 +627,50 @@ void cv::ogl::Buffer::copyFrom(InputArray arr, Target target, bool autoRelease) #endif } -void cv::ogl::Buffer::copyTo(OutputArray arr, Target target, bool autoRelease) const +void cv::ogl::Buffer::copyFrom(InputArray arr, gpu::Stream& stream, Target target, bool autoRelease) { #ifndef HAVE_OPENGL (void) arr; + (void) stream; (void) target; (void) autoRelease; throw_no_ogl(); #else + #ifndef HAVE_CUDA + (void) arr; + (void) stream; + (void) target; + (void) autoRelease; + throw_no_cuda(); + #else + GpuMat dmat = arr.getGpuMat(); + + create(dmat.size(), dmat.type(), target, autoRelease); + + impl_->copyFrom(dmat.data, dmat.step, dmat.cols * dmat.elemSize(), dmat.rows, gpu::StreamAccessor::getStream(stream)); + #endif +#endif +} + +void cv::ogl::Buffer::copyTo(OutputArray arr) const +{ +#ifndef HAVE_OPENGL + (void) arr; + throw_no_ogl(); +#else const int kind = arr.kind(); switch (kind) { case _InputArray::OPENGL_BUFFER: { - arr.getOGlBufferRef().copyFrom(*this, target, autoRelease); + arr.getOGlBufferRef().copyFrom(*this); break; } case _InputArray::GPU_MAT: { - #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + #ifndef HAVE_CUDA throw_no_cuda(); #else GpuMat& dmat = arr.getGpuMatRef(); @@ -684,6 +692,25 @@ void cv::ogl::Buffer::copyTo(OutputArray arr, Target target, bool autoRelease) c #endif } +void cv::ogl::Buffer::copyTo(OutputArray arr, gpu::Stream& stream) const +{ +#ifndef HAVE_OPENGL + (void) arr; + (void) stream; + throw_no_ogl(); +#else + #ifndef HAVE_CUDA + (void) arr; + (void) stream; + throw_no_cuda(); + #else + arr.create(rows_, cols_, type_); + GpuMat dmat = arr.getGpuMat(); + impl_->copyTo(dmat.data, dmat.step, dmat.cols * dmat.elemSize(), dmat.rows, gpu::StreamAccessor::getStream(stream)); + #endif +#endif +} + cv::ogl::Buffer cv::ogl::Buffer::clone(Target target, bool autoRelease) const { #ifndef HAVE_OPENGL @@ -745,7 +772,7 @@ GpuMat cv::ogl::Buffer::mapDevice() throw_no_ogl(); return GpuMat(); #else - #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + #ifndef HAVE_CUDA throw_no_cuda(); return GpuMat(); #else @@ -759,7 +786,7 @@ void cv::ogl::Buffer::unmapDevice() #ifndef HAVE_OPENGL throw_no_ogl(); #else - #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + #ifndef HAVE_CUDA throw_no_cuda(); #else impl_->unmapDevice(); @@ -767,6 +794,38 @@ void cv::ogl::Buffer::unmapDevice() #endif } +gpu::GpuMat cv::ogl::Buffer::mapDevice(gpu::Stream& stream) +{ +#ifndef HAVE_OPENGL + (void) stream; + throw_no_ogl(); + return GpuMat(); +#else + #ifndef HAVE_CUDA + (void) stream; + throw_no_cuda(); + return GpuMat(); + #else + return GpuMat(rows_, cols_, type_, impl_->mapDevice(gpu::StreamAccessor::getStream(stream))); + #endif +#endif +} + +void cv::ogl::Buffer::unmapDevice(gpu::Stream& stream) +{ +#ifndef HAVE_OPENGL + (void) stream; + throw_no_ogl(); +#else + #ifndef HAVE_CUDA + (void) stream; + throw_no_cuda(); + #else + impl_->unmapDevice(gpu::StreamAccessor::getStream(stream)); + #endif +#endif +} + unsigned int cv::ogl::Buffer::bufId() const { #ifndef HAVE_OPENGL @@ -824,12 +883,13 @@ const Ptr cv::ogl::Texture2D::Impl::empty() return p; } -cv::ogl::Texture2D::Impl::Impl() : texId_(0), autoRelease_(true) +cv::ogl::Texture2D::Impl::Impl() : texId_(0), autoRelease_(false) { } cv::ogl::Texture2D::Impl::Impl(GLuint atexId, bool autoRelease) : texId_(atexId), autoRelease_(autoRelease) { + CV_Assert( gl::IsTexture(atexId) == gl::TRUE_ ); } cv::ogl::Texture2D::Impl::Impl(GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels, bool autoRelease) : texId_(0), autoRelease_(autoRelease) @@ -935,16 +995,6 @@ cv::ogl::Texture2D::Texture2D(Size asize, Format aformat, unsigned int atexId, b #endif } -cv::ogl::Texture2D::Texture2D(int arows, int acols, Format aformat, bool autoRelease) : rows_(0), cols_(0), format_(NONE) -{ - create(arows, acols, aformat, autoRelease); -} - -cv::ogl::Texture2D::Texture2D(Size asize, Format aformat, bool autoRelease) : rows_(0), cols_(0), format_(NONE) -{ - create(asize, aformat, autoRelease); -} - cv::ogl::Texture2D::Texture2D(InputArray arr, bool autoRelease) : rows_(0), cols_(0), format_(NONE) { #ifndef HAVE_OPENGL @@ -985,7 +1035,7 @@ cv::ogl::Texture2D::Texture2D(InputArray arr, bool autoRelease) : rows_(0), cols case _InputArray::GPU_MAT: { - #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + #ifndef HAVE_CUDA throw_no_cuda(); #else GpuMat dmat = arr.getGpuMat(); @@ -1098,7 +1148,7 @@ void cv::ogl::Texture2D::copyFrom(InputArray arr, bool autoRelease) case _InputArray::GPU_MAT: { - #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + #ifndef HAVE_CUDA throw_no_cuda(); #else GpuMat dmat = arr.getGpuMat(); @@ -1149,7 +1199,7 @@ void cv::ogl::Texture2D::copyTo(OutputArray arr, int ddepth, bool autoRelease) c case _InputArray::GPU_MAT: { - #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + #ifndef HAVE_CUDA throw_no_cuda(); #else ogl::Buffer buf(rows_, cols_, CV_MAKE_TYPE(ddepth, cn), ogl::Buffer::PIXEL_PACK_BUFFER); @@ -1201,10 +1251,6 @@ template <> void cv::Ptr::delete_obj() //////////////////////////////////////////////////////////////////////// // ogl::Arrays -cv::ogl::Arrays::Arrays() : size_(0) -{ -} - void cv::ogl::Arrays::setVertexArray(InputArray vertex) { const int cn = vertex.channels(); diff --git a/modules/gpu/test/test_opengl.cpp b/modules/gpu/test/test_opengl.cpp index 41bdc8e..6166081 100644 --- a/modules/gpu/test/test_opengl.cpp +++ b/modules/gpu/test/test_opengl.cpp @@ -198,7 +198,8 @@ GPU_TEST_P(Buffer, CopyToBuffer) cv::ogl::Buffer buf(gold, cv::ogl::Buffer::ARRAY_BUFFER, true); cv::ogl::Buffer dst; - buf.copyTo(dst, cv::ogl::Buffer::ARRAY_BUFFER, true); + buf.copyTo(dst); + dst.setAutoRelease(true); EXPECT_NE(buf.bufId(), dst.bufId());