Fixed issue: Mat::copyTo(UMat) if device copy is obsolete. Added test.
authorAlexander Karsakov <alexander.karsakov@itseez.com>
Thu, 7 Aug 2014 08:31:50 +0000 (12:31 +0400)
committerAlexander Karsakov <alexander.karsakov@itseez.com>
Thu, 7 Aug 2014 09:16:02 +0000 (13:16 +0400)
modules/core/src/umatrix.cpp
modules/core/test/test_umat.cpp

index 494f3e3..ab8865d 100644 (file)
@@ -593,15 +593,16 @@ void* UMat::handle(int accessFlags) const
     if( !u )
         return 0;
 
-    if ((accessFlags & ACCESS_WRITE) != 0)
-        u->markHostCopyObsolete(true);
-
     // check flags: if CPU copy is newer, copy it back to GPU.
     if( u->deviceCopyObsolete() )
     {
         CV_Assert(u->refcount == 0);
         u->currAllocator->unmap(u);
     }
+
+    if ((accessFlags & ACCESS_WRITE) != 0)
+        u->markHostCopyObsolete(true);
+
     return u->handle;
 }
 
index d7ae7a9..8e51aad 100644 (file)
@@ -745,6 +745,24 @@ TEST(UMat, Sync)
     EXPECT_EQ(0, cvtest::norm(um.getMat(ACCESS_READ), cv::Mat(um.size(), um.type(), 19), NORM_INF));
 }
 
+TEST(UMat, CopyToIfDeviceCopyIsObsolete)
+{
+    UMat um(7, 2, CV_8UC1);
+    Mat m(um.size(), um.type());
+    m.setTo(Scalar::all(0));
+
+    {
+        // make obsolete device copy of UMat
+        Mat temp = um.getMat(ACCESS_WRITE);
+        temp.setTo(Scalar::all(10));
+    }
+
+    m.copyTo(um);
+    um.setTo(Scalar::all(17));
+
+    EXPECT_EQ(0, cvtest::norm(um.getMat(ACCESS_READ), Mat(um.size(), um.type(), 17), NORM_INF));
+}
+
 TEST(UMat, setOpenCL)
 {
     // save the current state