34 class Array2D :
public Data
46 Array2D(
const Array2D& rhs,
const CopyOp copyop = {}) :
52 _data = _allocate(
static_cast<size_t>(_width) *
static_cast<size_t>(_height));
56 for (
const auto& v : rhs) *(dest_v++) = v;
61 Array2D(uint32_t width, uint32_t height,
Properties in_properties = {}) :
62 Data(in_properties,
sizeof(value_type)),
67 _data = _allocate(
static_cast<size_t>(_width) *
static_cast<size_t>(_height));
71 Array2D(uint32_t width, uint32_t height, value_type* data,
Properties in_properties = {}) :
72 Data(in_properties,
sizeof(value_type)),
75 _height(height) {
dirty(); }
77 Array2D(uint32_t width, uint32_t height,
const value_type& value,
Properties in_properties = {}) :
78 Data(in_properties,
sizeof(value_type)),
83 _data = _allocate(
static_cast<size_t>(_width) *
static_cast<size_t>(_height));
86 for (
auto& v : *
this) v = value;
91 Array2D(
ref_ptr<Data> data, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height,
Properties in_properties = {}) :
97 assign(data, offset, stride, width, height, in_properties);
100 template<
typename... Args>
111 size_t sizeofObject() const noexcept
override {
return sizeof(Array2D); }
112 const char* className() const noexcept
override {
return type_name<Array2D>(); }
113 const std::type_info&
type_info() const noexcept
override {
return typeid(*this); }
114 bool is_compatible(
const std::type_info& type)
const noexcept override {
return typeid(
Array2D) == type || Data::is_compatible(type); }
117 void accept(Visitor& visitor)
override;
118 void accept(ConstVisitor& visitor)
const override;
120 void read(Input& input)
override
122 size_t original_size = size();
126 uint32_t w = input.readValue<uint32_t>(
"width");
127 uint32_t h = input.readValue<uint32_t>(
"height");
129 if (
auto data_storage = input.readObject<Data>(
"storage"))
131 uint32_t offset = input.readValue<uint32_t>(
"offset");
136 if (input.matchPropertyName(
"data"))
138 size_t new_size = computeValueCountIncludingMipmaps(w, h, 1,
properties.maxNumMipmaps);
142 if (original_size != new_size)
145 _data = _allocate(new_size);
150 _data = _allocate(new_size);
158 if (_data) input.read(new_size, _data);
164 void write(Output& output)
const override
168 output.writeValue<uint32_t>(
"width", _width);
169 output.writeValue<uint32_t>(
"height", _height);
171 output.writeObject(
"storage", _storage);
174 auto offset = (
reinterpret_cast<uintptr_t
>(_data) -
reinterpret_cast<uintptr_t
>(_storage->dataPointer()));
175 output.writeValue<uint32_t>(
"offset", offset);
179 output.writePropertyName(
"data");
180 output.write(valueCount(), _data);
181 output.writeEndOfLine();
184 size_t size()
const {
return (
properties.maxNumMipmaps <= 1) ? (
static_cast<size_t>(_width) *
static_cast<size_t>(_height)) : computeValueCountIncludingMipmaps(_width, _height, 1,
properties.maxNumMipmaps); }
186 bool available()
const {
return _data !=
nullptr; }
187 bool empty()
const {
return _data ==
nullptr; }
199 Array2D& operator=(
const Array2D& rhs)
201 if (&rhs ==
this)
return *
this;
207 _height = rhs._height;
209 _data = _allocate(
static_cast<size_t>(_width) *
static_cast<size_t>(_height));
213 for (
const auto& v : rhs) *(dest_v++) = v;
221 void assign(uint32_t width, uint32_t height, value_type* data,
Properties in_properties = {})
235 void assign(ref_ptr<Data> storage, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height,
Properties in_properties = {})
242 if (_storage && _storage->dataPointer())
244 _data =
reinterpret_cast<value_type*
>(
reinterpret_cast<uint8_t*
>(_storage->dataPointer()) + offset);
260 void* dataRelease()
override
276 size_t valueSize()
const override {
return sizeof(value_type); }
277 size_t valueCount()
const override {
return size(); }
279 bool dataAvailable()
const override {
return available(); }
280 size_t dataSize()
const override {
return size() *
properties.stride; }
282 void* dataPointer()
override {
return _data; }
283 const void* dataPointer()
const override {
return _data; }
285 void* dataPointer(
size_t i)
override {
return data(i); }
286 const void* dataPointer(
size_t i)
const override {
return data(i); }
288 uint32_t dimensions()
const override {
return 2; }
289 uint32_t width()
const override {
return _width; }
290 uint32_t height()
const override {
return _height; }
291 uint32_t depth()
const override {
return 1; }
293 value_type* data() {
return _data; }
294 const value_type* data()
const {
return _data; }
296 inline value_type* data(
size_t i) {
return reinterpret_cast<value_type*
>(
reinterpret_cast<uint8_t*
>(_data) + i *
static_cast<size_t>(
properties.stride)); }
297 inline const value_type* data(
size_t i)
const {
return reinterpret_cast<const value_type*
>(
reinterpret_cast<const uint8_t*
>(_data) + i *
static_cast<size_t>(
properties.stride)); }
299 size_t index(uint32_t i, uint32_t j)
const noexcept {
return static_cast<size_t>(j) *
static_cast<size_t>(_width) +
static_cast<size_t>(i); }
301 value_type& operator[](
size_t i) {
return *data(i); }
302 const value_type& operator[](
size_t i)
const {
return *data(i); }
304 value_type& at(
size_t i) {
return *data(i); }
305 const value_type& at(
size_t i)
const {
return *data(i); }
307 value_type& operator()(uint32_t i, uint32_t j) {
return *data(index(i, j)); }
308 const value_type& operator()(uint32_t i, uint32_t j)
const {
return *data(index(i, j)); }
310 value_type& at(uint32_t i, uint32_t j) {
return *data(index(i, j)); }
311 const value_type& at(uint32_t i, uint32_t j)
const {
return *data(index(i, j)); }
313 void set(
size_t i,
const value_type& v) { *data(i) = v; }
314 void set(uint32_t i, uint32_t j,
const value_type& v) { *data(index(i, j)) = v; }
316 Data* storage() {
return _storage; }
317 const Data* storage()
const {
return _storage; }
319 iterator begin() {
return iterator{_data,
properties.stride}; }
320 const_iterator begin()
const {
return const_iterator{_data,
properties.stride}; }
322 iterator end() {
return iterator{data(_width * _height),
properties.stride}; }
323 const_iterator end()
const {
return const_iterator{data(_width * _height),
properties.stride}; }
331 value_type* _allocate(
size_t size)
const
335 else if (
properties.allocatorType == ALLOCATOR_TYPE_NEW_DELETE)
336 return new value_type[size];
337 else if (
properties.allocatorType == ALLOCATOR_TYPE_MALLOC_FREE)
338 return new (std::malloc(
sizeof(value_type) * size)) value_type[size];
340 return new (vsg::allocate(
sizeof(value_type) * size, ALLOCATOR_AFFINITY_DATA)) value_type[size];
345 if (!_storage && _data)
347 if (
properties.allocatorType == ALLOCATOR_TYPE_NEW_DELETE)
349 else if (
properties.allocatorType == ALLOCATOR_TYPE_MALLOC_FREE)
352 vsg::deallocate(_data);
360 ref_ptr<Data> _storage;