Opt: Use move semantics to avoid some data copies (#522)

* Opt: Use move semantics to avoid some data copies

* Update decoder_webidl_wrapper.cc
This commit is contained in:
Stefan Eilemann 2019-09-13 20:10:26 +02:00 committed by Ondrej Stava
parent ad58758459
commit 9e4d51bbcb
2 changed files with 26 additions and 170 deletions

View File

@ -46,7 +46,7 @@ void MetadataQuerier::GetIntEntryArray(const draco::Metadata &metadata,
const std::string name(entry_name); const std::string name(entry_name);
std::vector<int32_t> values; std::vector<int32_t> values;
metadata.GetEntryIntArray(name, &values); metadata.GetEntryIntArray(name, &values);
out_values->SetValues(values.data(), values.size()); out_values->MoveData(std::move(values));
} }
double MetadataQuerier::GetDoubleEntry(const Metadata &metadata, double MetadataQuerier::GetDoubleEntry(const Metadata &metadata,
@ -86,73 +86,6 @@ const char *MetadataQuerier::GetEntryName(const Metadata &metadata,
return entry_names_[entry_id].c_str(); return entry_names_[entry_id].c_str();
} }
DracoFloat32Array::DracoFloat32Array() {}
float DracoFloat32Array::GetValue(int index) const { return values_[index]; }
bool DracoFloat32Array::SetValues(const float *values, int count) {
if (values) {
values_.assign(values, values + count);
} else {
values_.resize(count);
}
return true;
}
DracoInt8Array::DracoInt8Array() {}
int8_t DracoInt8Array::GetValue(int index) const { return values_[index]; }
bool DracoInt8Array::SetValues(const int8_t *values, int count) {
values_.assign(values, values + count);
return true;
}
DracoUInt8Array::DracoUInt8Array() {}
uint8_t DracoUInt8Array::GetValue(int index) const { return values_[index]; }
bool DracoUInt8Array::SetValues(const uint8_t *values, int count) {
values_.assign(values, values + count);
return true;
}
DracoInt16Array::DracoInt16Array() {}
int16_t DracoInt16Array::GetValue(int index) const { return values_[index]; }
bool DracoInt16Array::SetValues(const int16_t *values, int count) {
values_.assign(values, values + count);
return true;
}
DracoUInt16Array::DracoUInt16Array() {}
uint16_t DracoUInt16Array::GetValue(int index) const { return values_[index]; }
bool DracoUInt16Array::SetValues(const uint16_t *values, int count) {
values_.assign(values, values + count);
return true;
}
DracoInt32Array::DracoInt32Array() {}
int DracoInt32Array::GetValue(int index) const { return values_[index]; }
bool DracoInt32Array::SetValues(const int *values, int count) {
values_.assign(values, values + count);
return true;
}
DracoUInt32Array::DracoUInt32Array() {}
uint32_t DracoUInt32Array::GetValue(int index) const { return values_[index]; }
bool DracoUInt32Array::SetValues(const uint32_t *values, int count) {
values_.assign(values, values + count);
return true;
}
Decoder::Decoder() {} Decoder::Decoder() {}
draco_EncodedGeometryType Decoder::GetEncodedGeometryType( draco_EncodedGeometryType Decoder::GetEncodedGeometryType(
@ -204,8 +137,9 @@ bool Decoder::GetFaceFromMesh(const Mesh &m,
draco::FaceIndex::ValueType face_id, draco::FaceIndex::ValueType face_id,
DracoInt32Array *out_values) { DracoInt32Array *out_values) {
const Mesh::Face &face = m.face(draco::FaceIndex(face_id)); const Mesh::Face &face = m.face(draco::FaceIndex(face_id));
return out_values->SetValues(reinterpret_cast<const int *>(face.data()), const auto ptr = reinterpret_cast<const int32_t *>(face.data());
face.size()); out_values->MoveData(std::vector<int32_t>({ptr, ptr + face.size()}));
return true;
} }
long Decoder::GetTriangleStripsFromMesh(const Mesh &m, long Decoder::GetTriangleStripsFromMesh(const Mesh &m,
@ -216,8 +150,7 @@ long Decoder::GetTriangleStripsFromMesh(const Mesh &m,
m, std::back_inserter(strip_indices))) { m, std::back_inserter(strip_indices))) {
return 0; return 0;
} }
if (!strip_values->SetValues(strip_indices.data(), strip_indices.size())) strip_values->MoveData(std::move(strip_indices));
return 0;
return stripifier.num_strips(); return stripifier.num_strips();
} }
@ -229,7 +162,8 @@ bool Decoder::GetAttributeFloat(const PointAttribute &pa,
float values[kMaxAttributeFloatValues] = {-2.0, -2.0, -2.0, -2.0}; float values[kMaxAttributeFloatValues] = {-2.0, -2.0, -2.0, -2.0};
if (!pa.ConvertValue<float>(draco::AttributeValueIndex(val_index), values)) if (!pa.ConvertValue<float>(draco::AttributeValueIndex(val_index), values))
return false; return false;
return out_values->SetValues(values, components); out_values->MoveData({values, values + components});
return true;
} }
bool Decoder::GetAttributeFloatForAllPoints(const PointCloud &pc, bool Decoder::GetAttributeFloatForAllPoints(const PointCloud &pc,
@ -242,7 +176,7 @@ bool Decoder::GetAttributeFloatForAllPoints(const PointCloud &pc,
float values[kMaxAttributeFloatValues] = {-2.0, -2.0, -2.0, -2.0}; float values[kMaxAttributeFloatValues] = {-2.0, -2.0, -2.0, -2.0};
int entry_id = 0; int entry_id = 0;
out_values->SetValues(nullptr, num_entries); out_values->Resize(num_entries);
for (draco::PointIndex i(0); i < num_points; ++i) { for (draco::PointIndex i(0); i < num_points; ++i) {
const draco::AttributeValueIndex val_index = pa.mapped_index(i); const draco::AttributeValueIndex val_index = pa.mapped_index(i);
if (!pa.ConvertValue<float>(val_index, values)) if (!pa.ConvertValue<float>(val_index, values))

View File

@ -33,108 +33,31 @@ typedef draco::Status::Code draco_StatusCode;
// To generate Draco JavaScript bindings you must have emscripten installed. // To generate Draco JavaScript bindings you must have emscripten installed.
// Then run make -f Makefile.emcc jslib. // Then run make -f Makefile.emcc jslib.
template <typename T>
class DracoFloat32Array { class DracoArray {
public: public:
DracoFloat32Array(); T GetValue(int index) const { return values_[index]; }
float GetValue(int index) const;
// In case |values| is nullptr, the data is allocated but not initialized. void Resize(int size) { values_.resize(size); }
bool SetValues(const float *values, int count); void MoveData(std::vector<T> &&values) { values_ = std::move(values); }
// Directly sets a value for a specific index. The array has to be already // Directly sets a value for a specific index. The array has to be already
// allocated at this point (using SetValues() method). // allocated at this point (using Resize() method).
void SetValue(int index, float val) { values_[index] = val; } void SetValue(int index, T val) { values_[index] = val; }
int size() const { return values_.size(); } int size() const { return values_.size(); }
private: private:
std::vector<float> values_; std::vector<T> values_;
}; };
class DracoInt8Array { using DracoFloat32Array = DracoArray<float>;
public: using DracoInt8Array = DracoArray<int8_t>;
DracoInt8Array(); using DracoUInt8Array = DracoArray<uint8_t>;
using DracoInt16Array = DracoArray<int16_t>;
int8_t GetValue(int index) const; using DracoUInt16Array = DracoArray<uint16_t>;
bool SetValues(const int8_t *values, int count); using DracoInt32Array = DracoArray<int32_t>;
using DracoUInt32Array = DracoArray<uint32_t>;
void SetValue(int index, int8_t val) { values_[index] = val; }
int size() const { return values_.size(); }
private:
std::vector<int8_t> values_;
};
class DracoUInt8Array {
public:
DracoUInt8Array();
uint8_t GetValue(int index) const;
bool SetValues(const uint8_t *values, int count);
void SetValue(int index, uint8_t val) { values_[index] = val; }
int size() const { return values_.size(); }
private:
std::vector<uint8_t> values_;
};
class DracoInt16Array {
public:
DracoInt16Array();
int16_t GetValue(int index) const;
bool SetValues(const int16_t *values, int count);
void SetValue(int index, int16_t val) { values_[index] = val; }
int size() const { return values_.size(); }
private:
std::vector<int16_t> values_;
};
class DracoUInt16Array {
public:
DracoUInt16Array();
uint16_t GetValue(int index) const;
bool SetValues(const uint16_t *values, int count);
void SetValue(int index, uint16_t val) { values_[index] = val; }
int size() const { return values_.size(); }
private:
std::vector<uint16_t> values_;
};
class DracoInt32Array {
public:
DracoInt32Array();
int32_t GetValue(int index) const;
bool SetValues(const int *values, int count);
void SetValue(int index, int32_t val) { values_[index] = val; }
int size() const { return values_.size(); }
private:
std::vector<int32_t> values_;
};
class DracoUInt32Array {
public:
DracoUInt32Array();
uint32_t GetValue(int index) const;
bool SetValues(const uint32_t *values, int count);
void SetValue(int index, uint32_t val) { values_[index] = val; }
int size() const { return values_.size(); }
private:
std::vector<uint32_t> values_;
};
class MetadataQuerier { class MetadataQuerier {
public: public:
@ -299,9 +222,8 @@ class Decoder {
pa.data_type() == draco_unsigned_type) && pa.data_type() == draco_unsigned_type) &&
pa.is_mapping_identity()) { pa.is_mapping_identity()) {
// Copy values directly to the output vector. // Copy values directly to the output vector.
out_values->SetValues(reinterpret_cast<const ValueTypeT *>( const auto ptr = pa.GetAddress(draco::AttributeValueIndex(0));
pa.GetAddress(draco::AttributeValueIndex(0))), out_values->MoveData({ptr, ptr + num_entries});
num_entries);
return true; return true;
} }
@ -309,7 +231,7 @@ class Decoder {
std::vector<ValueTypeT> values(components); std::vector<ValueTypeT> values(components);
int entry_id = 0; int entry_id = 0;
out_values->SetValues(nullptr, num_entries); out_values->Resize(num_entries);
for (draco::PointIndex i(0); i < num_points; ++i) { for (draco::PointIndex i(0); i < num_points; ++i) {
const draco::AttributeValueIndex val_index = pa.mapped_index(i); const draco::AttributeValueIndex val_index = pa.mapped_index(i);
if (!pa.ConvertValue<ValueTypeT>(val_index, &values[0])) if (!pa.ConvertValue<ValueTypeT>(val_index, &values[0]))