//
//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"
//! 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();
//! 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;
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;
//! 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();
//! 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;
void bind() const;
- int size() const { return size_; }
- bool empty() const { return size_ == 0; }
+ int size() const;
+ bool empty() const;
private:
int size_;
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 {
}
-#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__ */
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
(void) device;
throw_no_ogl();
#else
- #if !defined(HAVE_CUDA) || defined(CUDA_DISABLER)
+ #ifndef HAVE_CUDA
(void) device;
throw_no_cuda();
#else
////////////////////////////////////////////////////////////////////////
// CudaResource
-#if defined(HAVE_OPENGL) && defined(HAVE_CUDA) && !defined(CUDA_DISABLER)
+#if defined(HAVE_OPENGL) && defined(HAVE_CUDA)
namespace
{
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)
}
#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
#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
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:
{
case _InputArray::GPU_MAT:
{
- #if !defined HAVE_CUDA || defined(CUDA_DISABLER)
+ #ifndef HAVE_CUDA
throw_no_cuda();
#else
GpuMat dmat = arr.getGpuMat();
#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();
#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
throw_no_ogl();
return GpuMat();
#else
- #if !defined HAVE_CUDA || defined(CUDA_DISABLER)
+ #ifndef HAVE_CUDA
throw_no_cuda();
return GpuMat();
#else
#ifndef HAVE_OPENGL
throw_no_ogl();
#else
- #if !defined HAVE_CUDA || defined(CUDA_DISABLER)
+ #ifndef HAVE_CUDA
throw_no_cuda();
#else
impl_->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
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)
#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
case _InputArray::GPU_MAT:
{
- #if !defined HAVE_CUDA || defined(CUDA_DISABLER)
+ #ifndef HAVE_CUDA
throw_no_cuda();
#else
GpuMat dmat = arr.getGpuMat();
case _InputArray::GPU_MAT:
{
- #if !defined HAVE_CUDA || defined(CUDA_DISABLER)
+ #ifndef HAVE_CUDA
throw_no_cuda();
#else
GpuMat dmat = arr.getGpuMat();
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);
////////////////////////////////////////////////////////////////////////
// ogl::Arrays
-cv::ogl::Arrays::Arrays() : size_(0)
-{
-}
-
void cv::ogl::Arrays::setVertexArray(InputArray vertex)
{
const int cn = vertex.channels();