add oclMatExpr class to prevent extra allocations
authoryao <bitwangyaoyao@gmail.com>
Sat, 16 Feb 2013 03:05:23 +0000 (11:05 +0800)
committeryao <bitwangyaoyao@gmail.com>
Sat, 16 Feb 2013 03:05:23 +0000 (11:05 +0800)
modules/ocl/include/opencv2/ocl/matrix_operations.hpp
modules/ocl/include/opencv2/ocl/ocl.hpp
modules/ocl/src/arithm.cpp

index 4b617ce..13b19be 100644 (file)
@@ -48,9 +48,27 @@ namespace cv
 
     namespace ocl
     {
-        ////////////////////////////////////OpenCL kernel strings//////////////////////////
-        //extern const char *convertC3C4;
 
+        enum
+        {
+            MAT_ADD,
+            MAT_SUB,
+            MAT_MUL,
+            MAT_DIV
+        };
+
+        class oclMatExpr
+        {
+            public:
+                oclMatExpr(const oclMat& _a, const oclMat& _b, int _op)
+                    : a(_a), b(_b), op(_op){}
+                operator oclMat() const;
+                void assign(oclMat& m) const;
+
+            protected:
+                int op;
+                oclMat a, b;
+        };
         ////////////////////////////////////////////////////////////////////////
         //////////////////////////////// oclMat ////////////////////////////////
         ////////////////////////////////////////////////////////////////////////
@@ -237,6 +255,12 @@ namespace cv
             return *this;
         }
 
+        oclMat& oclMat::operator = (const oclMatExpr& expr)
+        {
+            expr.assign(*this);
+            return *this;
+        }
+
         /* Fixme! To be supported in OpenCL later. */
 #if 0
         template <class T> inline oclMat::operator DevMem2D_<T>() const
index e86207d..83cfb5a 100644 (file)
@@ -119,6 +119,7 @@ namespace cv
             Impl *impl;
         };
 
+        class CV_EXPORTS oclMatExpr;
         //////////////////////////////// oclMat ////////////////////////////////
         class CV_EXPORTS oclMat
         {
@@ -152,7 +153,7 @@ namespace cv
             oclMat &operator = (const oclMat &m);
             //! assignment operator. Perfom blocking upload to device.
             oclMat &operator = (const Mat &m);
-
+            oclMat& operator = (const oclMatExpr& expr);
 
             //! pefroms blocking upload data to oclMat.
             void upload(const cv::Mat &m);
@@ -296,6 +297,7 @@ namespace cv
             int wholecols;
         };
 
+
         ///////////////////// mat split and merge /////////////////////////////////
         //! Compose a multi-channel array from several single-channel arrays
         // Support all types
@@ -459,25 +461,24 @@ namespace cv
         // supports all types
         CV_EXPORTS void bitwise_xor(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat());
         CV_EXPORTS void bitwise_xor(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat());
-        //! computes convolution of two images
-
-        //! support only CV_32FC1 type
-
-        CV_EXPORTS void convolve(const oclMat &image, const oclMat &temp1, oclMat &result);
-
 
         //! Logical operators
         CV_EXPORTS oclMat operator ~ (const oclMat &src);
         CV_EXPORTS oclMat operator | (const oclMat &src1, const oclMat &src2);
         CV_EXPORTS oclMat operator & (const oclMat &src1, const oclMat &src2);
         CV_EXPORTS oclMat operator ^ (const oclMat &src1, const oclMat &src2);
-        CV_EXPORTS void cvtColor(const oclMat &src, oclMat &dst, int code , int dcn = 0);
 
         //! Mathematics operators
-        CV_EXPORTS oclMat operator + (const oclMat &src1, const oclMat &src2);
-        CV_EXPORTS oclMat operator - (const oclMat &src1, const oclMat &src2);
-        CV_EXPORTS oclMat operator * (const oclMat &src1, const oclMat &src2);
-        CV_EXPORTS oclMat operator / (const oclMat &src1, const oclMat &src2);
+        CV_EXPORTS oclMatExpr operator + (const oclMat &src1, const oclMat &src2);
+        CV_EXPORTS oclMatExpr operator - (const oclMat &src1, const oclMat &src2);
+        CV_EXPORTS oclMatExpr operator * (const oclMat &src1, const oclMat &src2);
+        CV_EXPORTS oclMatExpr operator / (const oclMat &src1, const oclMat &src2);
+        //! computes convolution of two images
+        //! support only CV_32FC1 type
+        CV_EXPORTS void convolve(const oclMat &image, const oclMat &temp1, oclMat &result);
+       CV_EXPORTS void cvtColor(const oclMat &src, oclMat &dst, int code , int dcn = 0);
 
         //////////////////////////////// Filter Engine ////////////////////////////////
 
index e43cf50..b9174e7 100644 (file)
@@ -2153,34 +2153,56 @@ cv::ocl::oclMat cv::ocl::operator ^ (const oclMat &src1, const oclMat &src2)
     return dst;
 }
 
-cv::ocl::oclMat cv::ocl::operator + (const oclMat &src1, const oclMat &src2)
+cv::ocl::oclMatExpr cv::ocl::operator + (const oclMat &src1, const oclMat &src2)
 {
-    oclMat dst;
-    add(src1, src2, dst);
+    oclMatExpr dst(src1, src2, cv::ocl::MAT_ADD);
     return dst;
 }
 
-cv::ocl::oclMat cv::ocl::operator - (const oclMat &src1, const oclMat &src2)
+cv::ocl::oclMatExpr cv::ocl::operator - (const oclMat &src1, const oclMat &src2)
 {
-    oclMat dst;
-    subtract(src1, src2, dst);
+    oclMatExpr dst(src1, src2, cv::ocl::MAT_SUB);
     return dst;
 }
 
-cv::ocl::oclMat cv::ocl::operator * (const oclMat &src1, const oclMat &src2)
+cv::ocl::oclMatExpr cv::ocl::operator * (const oclMat &src1, const oclMat &src2)
 {
-    oclMat dst;
-    multiply(src1, src2, dst);
+    oclMatExpr dst(src1, src2, cv::ocl::MAT_MUL);
     return dst;
 }
 
-cv::ocl::oclMat cv::ocl::operator / (const oclMat &src1, const oclMat &src2)
+cv::ocl::oclMatExpr cv::ocl::operator / (const oclMat &src1, const oclMat &src2)
 {
-    oclMat dst;
-    divide(src1, src2, dst);
+    oclMatExpr dst(src1, src2, cv::ocl::MAT_DIV);
     return dst;
 }
 
+void oclMatExpr::assign(oclMat& m) const
+{
+    switch (op)
+    {
+        case MAT_ADD:
+            add(a, b, m);
+            break;
+        case MAT_SUB:
+            subtract(a, b, m);
+            break;
+        case MAT_MUL:
+            multiply(a, b, m);
+            break;
+        case MAT_DIV:
+            divide(a, b, m);
+            break;
+    }
+}
+
+oclMatExpr::operator oclMat() const
+{
+    oclMat m;
+    assign(m);
+    return m;
+}
+
 //////////////////////////////////////////////////////////////////////////////
 /////////////////////////////// transpose ////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////