Instead of caching PNGImage results, cache mjCTexture and mjCHField assets.
PiperOrigin-RevId: 813307632 Change-Id: I9de8b46423f57240d22811571d0533b010ee1e2b
This commit is contained in:
committed by
Copybara-Service
parent
59d0676dcc
commit
4d590afdad
+88
-35
@@ -80,22 +80,6 @@ PNGImage PNGImage::Load(const mjCBase* obj, mjResource* resource,
|
|||||||
LodePNGColorType color_type) {
|
LodePNGColorType color_type) {
|
||||||
PNGImage image;
|
PNGImage image;
|
||||||
image.color_type_ = color_type;
|
image.color_type_ = color_type;
|
||||||
mjCCache *cache = reinterpret_cast<mjCCache*>(mj_getCache()->impl_);
|
|
||||||
|
|
||||||
// cache callback
|
|
||||||
auto callback = [&image](const void* data) {
|
|
||||||
const PNGImage *cached_image = static_cast<const PNGImage*>(data);
|
|
||||||
if (cached_image->color_type_ == image.color_type_) {
|
|
||||||
image = *cached_image;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// try loading from cache
|
|
||||||
if (cache && cache->PopulateData(resource->name, resource, callback)) {
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
// open PNG resource
|
// open PNG resource
|
||||||
const unsigned char* buffer;
|
const unsigned char* buffer;
|
||||||
@@ -146,16 +130,6 @@ PNGImage PNGImage::Load(const mjCBase* obj, mjResource* resource,
|
|||||||
throw mjCError(obj, "%s", ss.str().c_str());
|
throw mjCError(obj, "%s", ss.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert raw image data into cache
|
|
||||||
if (cache) {
|
|
||||||
PNGImage *cached_image = new PNGImage(image);;
|
|
||||||
std::size_t size = image.Size();
|
|
||||||
std::shared_ptr<const void> cached_data(cached_image, +[] (const void* data) {
|
|
||||||
delete static_cast<const PNGImage*>(data);
|
|
||||||
});
|
|
||||||
cache->Insert("", resource->name, resource, cached_data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4397,6 +4371,12 @@ mjCHField::~mjCHField() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string mjCHField::GetCacheId(const mjResource* resource, const std::string& asset_type) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "mjCHField:" << resource->name << ";ARGS:content_type=" << asset_type;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// load elevation data from custom format
|
// load elevation data from custom format
|
||||||
void mjCHField::LoadCustom(mjResource* resource) {
|
void mjCHField::LoadCustom(mjResource* resource) {
|
||||||
@@ -4493,6 +4473,8 @@ void mjCHField::Compile(const mjVFS* vfs) {
|
|||||||
throw mjCError(this, "hfield specified from file and manually");
|
throw mjCError(this, "hfield specified from file and manually");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mjCCache* cache = reinterpret_cast<mjCCache*>(mj_getCache()->impl_);
|
||||||
|
|
||||||
std::string asset_type = GetAssetContentType(file_, content_type_);
|
std::string asset_type = GetAssetContentType(file_, content_type_);
|
||||||
|
|
||||||
// fallback to custom
|
// fallback to custom
|
||||||
@@ -4514,16 +4496,46 @@ void mjCHField::Compile(const mjVFS* vfs) {
|
|||||||
FilePath filename = meshdir_ + FilePath(file_);
|
FilePath filename = meshdir_ + FilePath(file_);
|
||||||
mjResource* resource = LoadResource(modelfiledir_.Str(), filename.Str(), vfs);
|
mjResource* resource = LoadResource(modelfiledir_.Str(), filename.Str(), vfs);
|
||||||
|
|
||||||
try {
|
struct CachedHField {
|
||||||
if (asset_type == "image/png") {
|
int nrow, ncol;
|
||||||
LoadPNG(resource);
|
std::vector<float> data;
|
||||||
} else {
|
};
|
||||||
LoadCustom(resource);
|
|
||||||
|
// cache callback
|
||||||
|
auto callback = [&](const void* cached_data) {
|
||||||
|
const CachedHField* cached_hfield =
|
||||||
|
static_cast<const CachedHField*>(cached_data);
|
||||||
|
nrow = cached_hfield->nrow;
|
||||||
|
ncol = cached_hfield->ncol;
|
||||||
|
this->data = cached_hfield->data;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// try loading from cache
|
||||||
|
if (cache && cache->PopulateData(GetCacheId(resource, asset_type), resource, callback)) {
|
||||||
|
mju_closeResource(resource);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (asset_type == "image/png") {
|
||||||
|
LoadPNG(resource);
|
||||||
|
} else {
|
||||||
|
LoadCustom(resource);
|
||||||
|
}
|
||||||
|
} catch(mjCError err) {
|
||||||
|
mju_closeResource(resource);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache) {
|
||||||
|
CachedHField* cached_hfield = new CachedHField;
|
||||||
|
cached_hfield->nrow = nrow;
|
||||||
|
cached_hfield->ncol = ncol;
|
||||||
|
cached_hfield->data = this->data;
|
||||||
|
std::size_t size = sizeof(CachedHField) + this->data.size() * sizeof(float);
|
||||||
|
std::shared_ptr<CachedHField> cached_data{cached_hfield};
|
||||||
|
cache->Insert("", GetCacheId(resource, asset_type), resource, cached_data, size);
|
||||||
}
|
}
|
||||||
mju_closeResource(resource);
|
mju_closeResource(resource);
|
||||||
} catch(mjCError err) {
|
|
||||||
mju_closeResource(resource);
|
|
||||||
throw err;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5021,10 +5033,36 @@ void mjCTexture::FlipIfNeeded(std::vector<std::byte>& image, unsigned int w,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string mjCTexture::GetCacheId(const mjResource* resource, const std::string& asset_type) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << resource->name << ";ARGS:content_type=" << asset_type << ",nchannel=" << nchannel
|
||||||
|
<< ",hflip=" << hflip << ",vflip=" << vflip << ";";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
// load from PNG or custom file, flip if specified
|
// load from PNG or custom file, flip if specified
|
||||||
void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
|
void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
|
||||||
std::vector<std::byte>& image,
|
std::vector<std::byte>& image,
|
||||||
unsigned int& w, unsigned int& h, bool& is_srgb) {
|
unsigned int& w, unsigned int& h, bool& is_srgb) {
|
||||||
|
mjCCache* cache = reinterpret_cast<mjCCache*>(mj_getCache()->impl_);
|
||||||
|
|
||||||
|
struct CachedImage {
|
||||||
|
unsigned int w, h, n_ch;
|
||||||
|
bool is_srgb;
|
||||||
|
std::vector<std::byte> image;
|
||||||
|
};
|
||||||
|
|
||||||
|
// cache callback
|
||||||
|
auto callback = [&](const void* data) {
|
||||||
|
const CachedImage* cached_image =
|
||||||
|
static_cast<const CachedImage*>(data);
|
||||||
|
w = cached_image->w;
|
||||||
|
h = cached_image->h;
|
||||||
|
is_srgb = cached_image->is_srgb;
|
||||||
|
image = cached_image->image;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
std::string asset_type = GetAssetContentType(filename, content_type_);
|
std::string asset_type = GetAssetContentType(filename, content_type_);
|
||||||
|
|
||||||
// fallback to custom
|
// fallback to custom
|
||||||
@@ -5036,7 +5074,12 @@ void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
|
|||||||
throw mjCError(this, "unsupported content type: '%s'", asset_type.c_str());
|
throw mjCError(this, "unsupported content type: '%s'", asset_type.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try loading from cache
|
||||||
mjResource* resource = LoadResource(modelfiledir_.Str(), filename, vfs);
|
mjResource* resource = LoadResource(modelfiledir_.Str(), filename, vfs);
|
||||||
|
if (cache && cache->PopulateData(GetCacheId(resource, asset_type), resource, callback)) {
|
||||||
|
mju_closeResource(resource);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (asset_type == "image/png") {
|
if (asset_type == "image/png") {
|
||||||
@@ -5049,13 +5092,23 @@ void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
|
|||||||
} else {
|
} else {
|
||||||
LoadCustom(resource, image, w, h, is_srgb);
|
LoadCustom(resource, image, w, h, is_srgb);
|
||||||
}
|
}
|
||||||
mju_closeResource(resource);
|
|
||||||
} catch(mjCError err) {
|
} catch(mjCError err) {
|
||||||
mju_closeResource(resource);
|
mju_closeResource(resource);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlipIfNeeded(image, w, h);
|
FlipIfNeeded(image, w, h);
|
||||||
|
if (cache) {
|
||||||
|
CachedImage* cached_texture = new CachedImage;
|
||||||
|
cached_texture->w = w;
|
||||||
|
cached_texture->h = h;
|
||||||
|
cached_texture->is_srgb = is_srgb;
|
||||||
|
cached_texture->image = image;
|
||||||
|
std::size_t size = sizeof(CachedImage) + image.size();
|
||||||
|
std::shared_ptr<CachedImage> cached_data{cached_texture};
|
||||||
|
cache->Insert("", GetCacheId(resource, asset_type), resource, cached_data, size);
|
||||||
|
}
|
||||||
|
mju_closeResource(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
// load 2D
|
// load 2D
|
||||||
|
|||||||
@@ -1395,6 +1395,7 @@ class mjCHField : public mjCHField_, private mjsHField {
|
|||||||
private:
|
private:
|
||||||
void Compile(const mjVFS* vfs); // compiler
|
void Compile(const mjVFS* vfs); // compiler
|
||||||
|
|
||||||
|
std::string GetCacheId(const mjResource* resource, const std::string& asset_type);
|
||||||
void LoadCustom(mjResource* resource); // load from custom format
|
void LoadCustom(mjResource* resource); // load from custom format
|
||||||
void LoadPNG(mjResource* resource); // load from PNG format
|
void LoadPNG(mjResource* resource); // load from PNG format
|
||||||
};
|
};
|
||||||
@@ -1444,11 +1445,14 @@ class mjCTexture : public mjCTexture_, private mjsTexture {
|
|||||||
private:
|
private:
|
||||||
void Compile(const mjVFS* vfs); // compiler
|
void Compile(const mjVFS* vfs); // compiler
|
||||||
|
|
||||||
void Builtin2D(void); // make builtin 2D
|
// store texture into asset cache
|
||||||
void BuiltinCube(void); // make builtin cube
|
std::string GetCacheId(const mjResource* resource, const std::string& asset_type);
|
||||||
void Load2D(std::string filename, const mjVFS* vfs); // load 2D from file
|
void Builtin2D(void); // make builtin 2D
|
||||||
void LoadCubeSingle(std::string filename, const mjVFS* vfs); // load cube from single file
|
void BuiltinCube(void); // make builtin cube
|
||||||
void LoadCubeSeparate(const mjVFS* vfs); // load cube from separate files
|
void Load2D(std::string filename, const mjVFS* vfs); // load 2D from file
|
||||||
|
void LoadCubeSingle(std::string filename,
|
||||||
|
const mjVFS* vfs); // load cube from single file
|
||||||
|
void LoadCubeSeparate(const mjVFS* vfs); // load cube from separate files
|
||||||
|
|
||||||
void FlipIfNeeded(std::vector<std::byte>& image, unsigned int w, unsigned int h);
|
void FlipIfNeeded(std::vector<std::byte>& image, unsigned int w, unsigned int h);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user