diff --git a/modules/core/src/umatrix.cpp b/modules/core/src/umatrix.cpp index 494f3e3c0..ab8865d04 100644 --- a/modules/core/src/umatrix.cpp +++ b/modules/core/src/umatrix.cpp @@ -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; } diff --git a/modules/core/test/test_umat.cpp b/modules/core/test/test_umat.cpp index d7ae7a938..8e51aadad 100644 --- a/modules/core/test/test_umat.cpp +++ b/modules/core/test/test_umat.cpp @@ -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