Skip to content

Commit 4d590af

Browse files
havesscopybara-github
authored andcommitted
Instead of caching PNGImage results, cache mjCTexture and mjCHField assets.
PiperOrigin-RevId: 813307632 Change-Id: I9de8b46423f57240d22811571d0533b010ee1e2b
1 parent 59d0676 commit 4d590af

File tree

2 files changed

+97
-40
lines changed

2 files changed

+97
-40
lines changed

src/user/user_objects.cc

Lines changed: 88 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -80,22 +80,6 @@ PNGImage PNGImage::Load(const mjCBase* obj, mjResource* resource,
8080
LodePNGColorType color_type) {
8181
PNGImage image;
8282
image.color_type_ = color_type;
83-
mjCCache *cache = reinterpret_cast<mjCCache*>(mj_getCache()->impl_);
84-
85-
// cache callback
86-
auto callback = [&image](const void* data) {
87-
const PNGImage *cached_image = static_cast<const PNGImage*>(data);
88-
if (cached_image->color_type_ == image.color_type_) {
89-
image = *cached_image;
90-
return true;
91-
}
92-
return false;
93-
};
94-
95-
// try loading from cache
96-
if (cache && cache->PopulateData(resource->name, resource, callback)) {
97-
return image;
98-
}
9983

10084
// open PNG resource
10185
const unsigned char* buffer;
@@ -146,16 +130,6 @@ PNGImage PNGImage::Load(const mjCBase* obj, mjResource* resource,
146130
throw mjCError(obj, "%s", ss.str().c_str());
147131
}
148132

149-
// insert raw image data into cache
150-
if (cache) {
151-
PNGImage *cached_image = new PNGImage(image);;
152-
std::size_t size = image.Size();
153-
std::shared_ptr<const void> cached_data(cached_image, +[] (const void* data) {
154-
delete static_cast<const PNGImage*>(data);
155-
});
156-
cache->Insert("", resource->name, resource, cached_data, size);
157-
}
158-
159133
return image;
160134
}
161135

@@ -4397,6 +4371,12 @@ mjCHField::~mjCHField() {
43974371
}
43984372

43994373

4374+
std::string mjCHField::GetCacheId(const mjResource* resource, const std::string& asset_type) {
4375+
std::stringstream ss;
4376+
ss << "mjCHField:" << resource->name << ";ARGS:content_type=" << asset_type;
4377+
return ss.str();
4378+
}
4379+
44004380

44014381
// load elevation data from custom format
44024382
void mjCHField::LoadCustom(mjResource* resource) {
@@ -4493,6 +4473,8 @@ void mjCHField::Compile(const mjVFS* vfs) {
44934473
throw mjCError(this, "hfield specified from file and manually");
44944474
}
44954475

4476+
mjCCache* cache = reinterpret_cast<mjCCache*>(mj_getCache()->impl_);
4477+
44964478
std::string asset_type = GetAssetContentType(file_, content_type_);
44974479

44984480
// fallback to custom
@@ -4514,16 +4496,46 @@ void mjCHField::Compile(const mjVFS* vfs) {
45144496
FilePath filename = meshdir_ + FilePath(file_);
45154497
mjResource* resource = LoadResource(modelfiledir_.Str(), filename.Str(), vfs);
45164498

4517-
try {
4518-
if (asset_type == "image/png") {
4519-
LoadPNG(resource);
4520-
} else {
4521-
LoadCustom(resource);
4522-
}
4499+
struct CachedHField {
4500+
int nrow, ncol;
4501+
std::vector<float> data;
4502+
};
4503+
4504+
// cache callback
4505+
auto callback = [&](const void* cached_data) {
4506+
const CachedHField* cached_hfield =
4507+
static_cast<const CachedHField*>(cached_data);
4508+
nrow = cached_hfield->nrow;
4509+
ncol = cached_hfield->ncol;
4510+
this->data = cached_hfield->data;
4511+
return true;
4512+
};
4513+
4514+
// try loading from cache
4515+
if (cache && cache->PopulateData(GetCacheId(resource, asset_type), resource, callback)) {
45234516
mju_closeResource(resource);
4524-
} catch(mjCError err) {
4517+
} else {
4518+
try {
4519+
if (asset_type == "image/png") {
4520+
LoadPNG(resource);
4521+
} else {
4522+
LoadCustom(resource);
4523+
}
4524+
} catch(mjCError err) {
4525+
mju_closeResource(resource);
4526+
throw err;
4527+
}
4528+
4529+
if (cache) {
4530+
CachedHField* cached_hfield = new CachedHField;
4531+
cached_hfield->nrow = nrow;
4532+
cached_hfield->ncol = ncol;
4533+
cached_hfield->data = this->data;
4534+
std::size_t size = sizeof(CachedHField) + this->data.size() * sizeof(float);
4535+
std::shared_ptr<CachedHField> cached_data{cached_hfield};
4536+
cache->Insert("", GetCacheId(resource, asset_type), resource, cached_data, size);
4537+
}
45254538
mju_closeResource(resource);
4526-
throw err;
45274539
}
45284540
}
45294541

@@ -5021,10 +5033,36 @@ void mjCTexture::FlipIfNeeded(std::vector<std::byte>& image, unsigned int w,
50215033
}
50225034
}
50235035

5036+
std::string mjCTexture::GetCacheId(const mjResource* resource, const std::string& asset_type) {
5037+
std::stringstream ss;
5038+
ss << resource->name << ";ARGS:content_type=" << asset_type << ",nchannel=" << nchannel
5039+
<< ",hflip=" << hflip << ",vflip=" << vflip << ";";
5040+
return ss.str();
5041+
}
5042+
50245043
// load from PNG or custom file, flip if specified
50255044
void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
50265045
std::vector<std::byte>& image,
50275046
unsigned int& w, unsigned int& h, bool& is_srgb) {
5047+
mjCCache* cache = reinterpret_cast<mjCCache*>(mj_getCache()->impl_);
5048+
5049+
struct CachedImage {
5050+
unsigned int w, h, n_ch;
5051+
bool is_srgb;
5052+
std::vector<std::byte> image;
5053+
};
5054+
5055+
// cache callback
5056+
auto callback = [&](const void* data) {
5057+
const CachedImage* cached_image =
5058+
static_cast<const CachedImage*>(data);
5059+
w = cached_image->w;
5060+
h = cached_image->h;
5061+
is_srgb = cached_image->is_srgb;
5062+
image = cached_image->image;
5063+
return true;
5064+
};
5065+
50285066
std::string asset_type = GetAssetContentType(filename, content_type_);
50295067

50305068
// fallback to custom
@@ -5036,7 +5074,12 @@ void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
50365074
throw mjCError(this, "unsupported content type: '%s'", asset_type.c_str());
50375075
}
50385076

5077+
// try loading from cache
50395078
mjResource* resource = LoadResource(modelfiledir_.Str(), filename, vfs);
5079+
if (cache && cache->PopulateData(GetCacheId(resource, asset_type), resource, callback)) {
5080+
mju_closeResource(resource);
5081+
return;
5082+
}
50405083

50415084
try {
50425085
if (asset_type == "image/png") {
@@ -5049,13 +5092,23 @@ void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
50495092
} else {
50505093
LoadCustom(resource, image, w, h, is_srgb);
50515094
}
5052-
mju_closeResource(resource);
50535095
} catch(mjCError err) {
50545096
mju_closeResource(resource);
50555097
throw err;
50565098
}
50575099

50585100
FlipIfNeeded(image, w, h);
5101+
if (cache) {
5102+
CachedImage* cached_texture = new CachedImage;
5103+
cached_texture->w = w;
5104+
cached_texture->h = h;
5105+
cached_texture->is_srgb = is_srgb;
5106+
cached_texture->image = image;
5107+
std::size_t size = sizeof(CachedImage) + image.size();
5108+
std::shared_ptr<CachedImage> cached_data{cached_texture};
5109+
cache->Insert("", GetCacheId(resource, asset_type), resource, cached_data, size);
5110+
}
5111+
mju_closeResource(resource);
50595112
}
50605113

50615114
// load 2D

src/user/user_objects.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,7 @@ class mjCHField : public mjCHField_, private mjsHField {
13951395
private:
13961396
void Compile(const mjVFS* vfs); // compiler
13971397

1398+
std::string GetCacheId(const mjResource* resource, const std::string& asset_type);
13981399
void LoadCustom(mjResource* resource); // load from custom format
13991400
void LoadPNG(mjResource* resource); // load from PNG format
14001401
};
@@ -1444,11 +1445,14 @@ class mjCTexture : public mjCTexture_, private mjsTexture {
14441445
private:
14451446
void Compile(const mjVFS* vfs); // compiler
14461447

1447-
void Builtin2D(void); // make builtin 2D
1448-
void BuiltinCube(void); // make builtin cube
1449-
void Load2D(std::string filename, const mjVFS* vfs); // load 2D from file
1450-
void LoadCubeSingle(std::string filename, const mjVFS* vfs); // load cube from single file
1451-
void LoadCubeSeparate(const mjVFS* vfs); // load cube from separate files
1448+
// store texture into asset cache
1449+
std::string GetCacheId(const mjResource* resource, const std::string& asset_type);
1450+
void Builtin2D(void); // make builtin 2D
1451+
void BuiltinCube(void); // make builtin cube
1452+
void Load2D(std::string filename, const mjVFS* vfs); // load 2D from file
1453+
void LoadCubeSingle(std::string filename,
1454+
const mjVFS* vfs); // load cube from single file
1455+
void LoadCubeSeparate(const mjVFS* vfs); // load cube from separate files
14521456

14531457
void FlipIfNeeded(std::vector<std::byte>& image, unsigned int w, unsigned int h);
14541458

0 commit comments

Comments
 (0)