mirror of
https://github.com/opencv/opencv.git
synced 2024-11-27 20:50:25 +08:00
Set and check allocator pointer for all cv::Mat instances.
This commit is contained in:
parent
2a333a6c86
commit
a15cd4b63d
@ -692,16 +692,13 @@ void Mat::create(int d, const int* _sizes, int _type)
|
|||||||
if( total() > 0 )
|
if( total() > 0 )
|
||||||
{
|
{
|
||||||
MatAllocator *a = allocator, *a0 = getDefaultAllocator();
|
MatAllocator *a = allocator, *a0 = getDefaultAllocator();
|
||||||
#ifdef HAVE_TGPU
|
|
||||||
if( !a || a == tegra::getAllocator() )
|
|
||||||
a = tegra::getAllocator(d, _sizes, _type);
|
|
||||||
#endif
|
|
||||||
if(!a)
|
if(!a)
|
||||||
a = a0;
|
a = a0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
u = a->allocate(dims, size, _type, 0, step.p, ACCESS_RW /* ignored */, USAGE_DEFAULT);
|
u = a->allocate(dims, size, _type, 0, step.p, ACCESS_RW /* ignored */, USAGE_DEFAULT);
|
||||||
CV_Assert(u != 0);
|
CV_Assert(u != 0);
|
||||||
|
allocator = a;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@ -709,6 +706,7 @@ void Mat::create(int d, const int* _sizes, int _type)
|
|||||||
throw;
|
throw;
|
||||||
u = a0->allocate(dims, size, _type, 0, step.p, ACCESS_RW /* ignored */, USAGE_DEFAULT);
|
u = a0->allocate(dims, size, _type, 0, step.p, ACCESS_RW /* ignored */, USAGE_DEFAULT);
|
||||||
CV_Assert(u != 0);
|
CV_Assert(u != 0);
|
||||||
|
allocator = a0;
|
||||||
}
|
}
|
||||||
CV_Assert( step[dims-1] == (size_t)CV_ELEM_SIZE(flags) );
|
CV_Assert( step[dims-1] == (size_t)CV_ELEM_SIZE(flags) );
|
||||||
}
|
}
|
||||||
|
144
modules/core/test/test_allocator.cpp
Normal file
144
modules/core/test/test_allocator.cpp
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
// of this distribution and at http://opencv.org/license.html.
|
||||||
|
#include "test_precomp.hpp"
|
||||||
|
|
||||||
|
namespace opencv_test { namespace {
|
||||||
|
|
||||||
|
// Dummy allocator implementation copied from the default OpenCV allocator with some simplifications
|
||||||
|
struct DummyAllocator: public cv::MatAllocator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DummyAllocator() {};
|
||||||
|
~DummyAllocator() {};
|
||||||
|
|
||||||
|
cv::UMatData* allocate(int dims, const int* sizes, int type,
|
||||||
|
void* data0, size_t* step, cv::AccessFlag flags,
|
||||||
|
cv::UMatUsageFlags usageFlags) const
|
||||||
|
{
|
||||||
|
CV_UNUSED(flags);
|
||||||
|
CV_UNUSED(usageFlags);
|
||||||
|
|
||||||
|
size_t total = CV_ELEM_SIZE(type);
|
||||||
|
for( int i = dims-1; i >= 0; i-- )
|
||||||
|
{
|
||||||
|
if( step )
|
||||||
|
{
|
||||||
|
if( data0 && step[i] != CV_AUTOSTEP )
|
||||||
|
{
|
||||||
|
CV_Assert(total <= step[i]);
|
||||||
|
total = step[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
step[i] = total;
|
||||||
|
}
|
||||||
|
total *= sizes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
uchar* data = nullptr;
|
||||||
|
if (data0)
|
||||||
|
{
|
||||||
|
data = (uchar*)data0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data = new uchar[total];
|
||||||
|
DummyAllocator::allocatedBytes += total;
|
||||||
|
DummyAllocator::allocations++;
|
||||||
|
}
|
||||||
|
cv::UMatData* u = new cv::UMatData(this);
|
||||||
|
u->data = u->origdata = data;
|
||||||
|
u->size = total;
|
||||||
|
if(data0)
|
||||||
|
u->flags |= cv::UMatData::USER_ALLOCATED;
|
||||||
|
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool allocate(cv::UMatData* u, cv::AccessFlag accessFlags, cv::UMatUsageFlags usageFlags) const
|
||||||
|
{
|
||||||
|
CV_UNUSED(accessFlags);
|
||||||
|
CV_UNUSED(usageFlags);
|
||||||
|
|
||||||
|
if(!u) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate(cv::UMatData* u) const
|
||||||
|
{
|
||||||
|
if(!u)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CV_Assert(u->urefcount == 0);
|
||||||
|
CV_Assert(u->refcount == 0);
|
||||||
|
if( !(u->flags & cv::UMatData::USER_ALLOCATED) )
|
||||||
|
{
|
||||||
|
delete[] u->origdata;
|
||||||
|
DummyAllocator::deallocations++;
|
||||||
|
u->origdata = 0;
|
||||||
|
}
|
||||||
|
delete u;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t allocatedBytes;
|
||||||
|
static int allocations;
|
||||||
|
static int deallocations;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t DummyAllocator::allocatedBytes = 0;
|
||||||
|
int DummyAllocator::allocations = 0;
|
||||||
|
int DummyAllocator::deallocations = 0;
|
||||||
|
|
||||||
|
cv::MatAllocator* getDummyAllocator()
|
||||||
|
{
|
||||||
|
static cv::MatAllocator* allocator = new DummyAllocator;
|
||||||
|
return allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AllocatorTest : public testing::Test {
|
||||||
|
void SetUp() override {
|
||||||
|
cv::MatAllocator* allocator = getDummyAllocator();
|
||||||
|
EXPECT_TRUE(allocator != nullptr);
|
||||||
|
cv::Mat::setDefaultAllocator(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown() override {
|
||||||
|
cv::Mat::setDefaultAllocator(cv::Mat::getStdAllocator());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(AllocatorTest, DummyAllocator)
|
||||||
|
{
|
||||||
|
cv::MatAllocator* dummy = getDummyAllocator();
|
||||||
|
|
||||||
|
DummyAllocator::allocatedBytes = 0;
|
||||||
|
DummyAllocator::allocations = 0;
|
||||||
|
DummyAllocator::deallocations = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
cv::Mat src1 = cv::Mat::ones (16, 16, CV_8UC1);
|
||||||
|
EXPECT_TRUE(!src1.empty());
|
||||||
|
EXPECT_EQ(src1.allocator, dummy);
|
||||||
|
|
||||||
|
cv::Mat src1_roi = src1(cv::Rect(2,2,8,8));
|
||||||
|
EXPECT_EQ(src1_roi.allocator, dummy);
|
||||||
|
|
||||||
|
cv::MatAllocator* standard = cv::Mat::getStdAllocator();
|
||||||
|
cv::Mat::setDefaultAllocator(standard);
|
||||||
|
cv::Mat src2 = cv::Mat::ones (16, 16, CV_8UC1);
|
||||||
|
EXPECT_TRUE(!src2.empty());
|
||||||
|
EXPECT_EQ(src2.allocator, standard);
|
||||||
|
|
||||||
|
src1.create(32, 32, CV_8UC1);
|
||||||
|
EXPECT_EQ(src1.allocator, dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t expect_allocated = 16*16*sizeof(uchar) + 32*32*sizeof(uchar);
|
||||||
|
EXPECT_EQ(expect_allocated, DummyAllocator::allocatedBytes);
|
||||||
|
|
||||||
|
// ROI should not trigger extra allocations
|
||||||
|
EXPECT_EQ(2, DummyAllocator::allocations);
|
||||||
|
EXPECT_EQ(2, DummyAllocator::deallocations);
|
||||||
|
}
|
||||||
|
|
||||||
|
}} // namespace
|
Loading…
Reference in New Issue
Block a user