Blender  V3.3
generic_virtual_array.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
4 
5 namespace blender {
6 
7 /* -------------------------------------------------------------------- */
11 void GVArrayImpl::materialize(const IndexMask mask, void *dst) const
12 {
13  for (const int64_t i : mask) {
14  void *elem_dst = POINTER_OFFSET(dst, type_->size() * i);
15  this->get(i, elem_dst);
16  }
17 }
18 
20 {
21  for (const int64_t i : mask) {
22  void *elem_dst = POINTER_OFFSET(dst, type_->size() * i);
23  this->get_to_uninitialized(i, elem_dst);
24  }
25 }
26 
28 {
29  for (const int64_t i : mask.index_range()) {
30  void *elem_dst = POINTER_OFFSET(dst, type_->size() * i);
31  this->get(mask[i], elem_dst);
32  }
33 }
34 
36 {
37  for (const int64_t i : mask.index_range()) {
38  void *elem_dst = POINTER_OFFSET(dst, type_->size() * i);
39  this->get_to_uninitialized(mask[i], elem_dst);
40  }
41 }
42 
43 void GVArrayImpl::get(const int64_t index, void *r_value) const
44 {
45  type_->destruct(r_value);
46  this->get_to_uninitialized(index, r_value);
47 }
48 
50 {
51  return {};
52 }
53 
54 bool GVArrayImpl::try_assign_VArray(void *UNUSED(varray)) const
55 {
56  return false;
57 }
58 
61 /* -------------------------------------------------------------------- */
65 void GVMutableArrayImpl::set_by_copy(const int64_t index, const void *value)
66 {
68  type_->copy_construct(value, buffer);
69  this->set_by_move(index, buffer);
71 }
72 
73 void GVMutableArrayImpl::set_by_relocate(const int64_t index, void *value)
74 {
75  this->set_by_move(index, value);
76  type_->destruct(value);
77 }
78 
80 {
81  const CommonVArrayInfo info = this->common_info();
82  if (info.type == CommonVArrayInfo::Type::Span) {
83  type_->copy_assign_n(src, const_cast<void *>(info.data), size_);
84  }
85  else {
86  for (int64_t i : IndexRange(size_)) {
87  this->set_by_copy(i, POINTER_OFFSET(src, type_->size() * i));
88  }
89  }
90 }
91 
92 void GVMutableArray::fill(const void *value)
93 {
94  const CommonVArrayInfo info = this->common_info();
95  if (info.type == CommonVArrayInfo::Type::Span) {
96  this->type().fill_assign_n(value, const_cast<void *>(info.data), this->size());
97  }
98  else {
99  for (int64_t i : IndexRange(this->size())) {
100  this->set_by_copy(i, value);
101  }
102  }
103 }
104 
106 {
107  return false;
108 }
109 
112 /* -------------------------------------------------------------------- */
116 void GVArrayImpl_For_GSpan::get(const int64_t index, void *r_value) const
117 {
118  type_->copy_assign(POINTER_OFFSET(data_, element_size_ * index), r_value);
119 }
120 
121 void GVArrayImpl_For_GSpan::get_to_uninitialized(const int64_t index, void *r_value) const
122 {
124 }
125 
126 void GVArrayImpl_For_GSpan::set_by_copy(const int64_t index, const void *value)
127 {
129 }
130 
131 void GVArrayImpl_For_GSpan::set_by_move(const int64_t index, void *value)
132 {
134 }
135 
136 void GVArrayImpl_For_GSpan::set_by_relocate(const int64_t index, void *value)
137 {
139 }
140 
142 {
144 }
145 
147 {
149 }
150 
152 {
154 }
155 
157 {
159 }
160 
162  void *dst) const
163 {
165 }
166 
169 /* -------------------------------------------------------------------- */
173 /* Generic virtual array where each element has the same value. The value is not owned. */
174 
175 void GVArrayImpl_For_SingleValueRef::get(const int64_t UNUSED(index), void *r_value) const
176 {
177  type_->copy_assign(value_, r_value);
178 }
180  void *r_value) const
181 {
182  type_->copy_construct(value_, r_value);
183 }
184 
186 {
188 }
189 
191 {
193 }
194 
196  void *dst) const
197 {
199 }
200 
202 {
203  type_->fill_assign_n(value_, dst, mask.size());
204 }
205 
207  void *dst) const
208 {
209  type_->fill_construct_n(value_, dst, mask.size());
210 }
211 
214 /* -------------------------------------------------------------------- */
218 /* Same as GVArrayImpl_For_SingleValueRef, but the value is owned. */
220  NonCopyable,
221  NonMovable {
222  public:
223  GVArrayImpl_For_SingleValue(const CPPType &type, const int64_t size, const void *value)
225  {
226  value_ = MEM_mallocN_aligned(type.size(), type.alignment(), __func__);
227  type.copy_construct(value, (void *)value_);
228  }
229 
231  {
232  type_->destruct((void *)value_);
233  MEM_freeN((void *)value_);
234  }
235 };
236 
239 /* -------------------------------------------------------------------- */
247 template<int BufferSize> class GVArrayImpl_For_SmallTrivialSingleValue : public GVArrayImpl {
248  private:
250 
251  public:
253  const int64_t size,
254  const void *value)
255  : GVArrayImpl(type, size)
256  {
258  BLI_assert(type.alignment() <= 8);
259  BLI_assert(type.size() <= BufferSize);
260  type.copy_construct(value, &buffer_);
261  }
262 
263  private:
264  void get(const int64_t UNUSED(index), void *r_value) const override
265  {
266  this->copy_value_to(r_value);
267  }
268  void get_to_uninitialized(const int64_t UNUSED(index), void *r_value) const override
269  {
270  this->copy_value_to(r_value);
271  }
272 
273  void copy_value_to(void *dst) const
274  {
275  memcpy(dst, &buffer_, type_->size());
276  }
277 
278  CommonVArrayInfo common_info() const override
279  {
280  return CommonVArrayInfo{CommonVArrayInfo::Type::Single, true, &buffer_};
281  }
282 };
283 
286 /* -------------------------------------------------------------------- */
290 GVArraySpan::GVArraySpan() = default;
291 
293  : GSpan(varray ? &varray.type() : nullptr), varray_(std::move(varray))
294 {
295  if (!varray_) {
296  return;
297  }
298 
299  size_ = varray_.size();
300  const CommonVArrayInfo info = varray_.common_info();
301  if (info.type == CommonVArrayInfo::Type::Span) {
302  data_ = info.data;
303  }
304  else {
305  owned_data_ = MEM_mallocN_aligned(type_->size() * size_, type_->alignment(), __func__);
306  varray_.materialize_to_uninitialized(IndexRange(size_), owned_data_);
307  data_ = owned_data_;
308  }
309 }
310 
312  : GSpan(other.type_ptr()), varray_(std::move(other.varray_)), owned_data_(other.owned_data_)
313 {
314  if (!varray_) {
315  return;
316  }
317 
318  size_ = varray_.size();
319  const CommonVArrayInfo info = varray_.common_info();
320  if (info.type == CommonVArrayInfo::Type::Span) {
321  data_ = info.data;
322  }
323  else {
324  data_ = owned_data_;
325  }
326  other.owned_data_ = nullptr;
327  other.data_ = nullptr;
328  other.size_ = 0;
329 }
330 
332 {
333  if (owned_data_ != nullptr) {
334  type_->destruct_n(owned_data_, size_);
335  MEM_freeN(owned_data_);
336  }
337 }
338 
340 {
341  if (this == &other) {
342  return *this;
343  }
344  std::destroy_at(this);
345  new (this) GVArraySpan(std::move(other));
346  return *this;
347 }
348 
351 /* -------------------------------------------------------------------- */
356 
357 GMutableVArraySpan::GMutableVArraySpan(GVMutableArray varray, const bool copy_values_to_span)
358  : GMutableSpan(varray ? &varray.type() : nullptr), varray_(std::move(varray))
359 {
360  if (!varray_) {
361  return;
362  }
363  size_ = varray_.size();
364  const CommonVArrayInfo info = varray_.common_info();
365  if (info.type == CommonVArrayInfo::Type::Span) {
366  data_ = const_cast<void *>(info.data);
367  }
368  else {
369  owned_data_ = MEM_mallocN_aligned(type_->size() * size_, type_->alignment(), __func__);
370  if (copy_values_to_span) {
371  varray_.materialize_to_uninitialized(IndexRange(size_), owned_data_);
372  }
373  else {
374  type_->default_construct_n(owned_data_, size_);
375  }
376  data_ = owned_data_;
377  }
378 }
379 
381  : GMutableSpan(other.type_ptr()),
382  varray_(std::move(other.varray_)),
383  owned_data_(other.owned_data_),
384  show_not_saved_warning_(other.show_not_saved_warning_)
385 {
386  if (!varray_) {
387  return;
388  }
389  size_ = varray_.size();
390  const CommonVArrayInfo info = varray_.common_info();
391  if (info.type == CommonVArrayInfo::Type::Span) {
392  data_ = const_cast<void *>(info.data);
393  }
394  else {
395  data_ = owned_data_;
396  }
397  other.owned_data_ = nullptr;
398  other.data_ = nullptr;
399  other.size_ = 0;
400 }
401 
403 {
404  if (varray_) {
405  if (show_not_saved_warning_) {
406  if (!save_has_been_called_) {
407  std::cout << "Warning: Call `save()` to make sure that changes persist in all cases.\n";
408  }
409  }
410  }
411  if (owned_data_ != nullptr) {
412  type_->destruct_n(owned_data_, size_);
413  MEM_freeN(owned_data_);
414  }
415 }
416 
418 {
419  if (this == &other) {
420  return *this;
421  }
422  std::destroy_at(this);
423  new (this) GMutableVArraySpan(std::move(other));
424  return *this;
425 }
426 
428 {
429  save_has_been_called_ = true;
430  if (data_ != owned_data_) {
431  return;
432  }
433  varray_.set_all(owned_data_);
434 }
435 
437 {
438  show_not_saved_warning_ = false;
439 }
440 
442 {
443  return varray_;
444 }
445 
448 /* -------------------------------------------------------------------- */
453  protected:
457 
458  public:
460  : GVArrayImpl(varray.type(), slice.size()),
461  varray_(std::move(varray)),
462  offset_(slice.start()),
463  slice_(slice)
464  {
465  BLI_assert(slice.one_after_last() <= varray_.size());
466  }
467 
468  void get(const int64_t index, void *r_value) const override
469  {
470  varray_.get(index + offset_, r_value);
471  }
472 
473  void get_to_uninitialized(const int64_t index, void *r_value) const override
474  {
475  varray_.get_to_uninitialized(index + offset_, r_value);
476  }
477 
478  CommonVArrayInfo common_info() const override
479  {
480  const CommonVArrayInfo internal_info = varray_.common_info();
481  switch (internal_info.type) {
483  return {};
484  }
487  internal_info.may_have_ownership,
488  POINTER_OFFSET(internal_info.data, type_->size() * offset_));
489  }
491  return internal_info;
492  }
493  }
495  return {};
496  }
497 
498  void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override
499  {
500  if (mask.is_range()) {
501  const IndexRange mask_range = mask.as_range();
502  const IndexRange offset_mask_range{mask_range.start() + offset_, mask_range.size()};
503  varray_.materialize_compressed_to_uninitialized(offset_mask_range, dst);
504  }
505  else {
506  Vector<int64_t, 32> offset_mask_indices(mask.size());
507  for (const int64_t i : mask.index_range()) {
508  offset_mask_indices[i] = mask[i] + offset_;
509  }
510  varray_.materialize_compressed_to_uninitialized(offset_mask_indices.as_span(), dst);
511  }
512  }
513 };
514 
517 /* -------------------------------------------------------------------- */
521 GVArrayCommon::GVArrayCommon(const GVArrayCommon &other) : storage_(other.storage_)
522 {
523  impl_ = this->impl_from_storage();
524 }
525 
526 GVArrayCommon::GVArrayCommon(GVArrayCommon &&other) noexcept : storage_(std::move(other.storage_))
527 {
528  impl_ = this->impl_from_storage();
529  other.storage_.reset();
530  other.impl_ = nullptr;
531 }
532 
534 {
535  storage_ = impl_;
536 }
537 
538 GVArrayCommon::GVArrayCommon(std::shared_ptr<const GVArrayImpl> impl) : impl_(impl.get())
539 {
540  if (impl) {
541  storage_ = std::move(impl);
542  }
543 }
544 
546 
547 void GVArrayCommon::materialize(void *dst) const
548 {
549  this->materialize(IndexMask(impl_->size()), dst);
550 }
551 
552 void GVArrayCommon::materialize(const IndexMask mask, void *dst) const
553 {
554  impl_->materialize(mask, dst);
555 }
556 
558 {
560 }
561 
563 {
564  BLI_assert(mask.min_array_size() <= impl_->size());
566 }
567 
569 {
571 }
572 
574 {
576 }
577 
579 {
580  if (this == &other) {
581  return;
582  }
583  storage_ = other.storage_;
584  impl_ = this->impl_from_storage();
585 }
586 
588 {
589  if (this == &other) {
590  return;
591  }
592  storage_ = std::move(other.storage_);
593  impl_ = this->impl_from_storage();
594  other.storage_.reset();
595  other.impl_ = nullptr;
596 }
597 
599 {
600  const CommonVArrayInfo info = impl_->common_info();
601  return info.type == CommonVArrayInfo::Type::Span;
602 }
603 
605 {
606  BLI_assert(this->is_span());
607  const CommonVArrayInfo info = impl_->common_info();
608  return GSpan(this->type(), info.data, this->size());
609 }
610 
612 {
613  const CommonVArrayInfo info = impl_->common_info();
614  return info.type == CommonVArrayInfo::Type::Single;
615 }
616 
617 void GVArrayCommon::get_internal_single(void *r_value) const
618 {
619  BLI_assert(this->is_single());
620  const CommonVArrayInfo info = impl_->common_info();
621  this->type().copy_assign(info.data, r_value);
622 }
623 
625 {
626  impl_->type().default_construct(r_value);
627  this->get_internal_single(r_value);
628 }
629 
631 {
632  if (!storage_.has_value()) {
633  return nullptr;
634  }
635  return storage_.extra_info().get_varray(storage_.get());
636 }
637 
639 {
640  return IndexRange(this->size());
641 }
642 
645 /* -------------------------------------------------------------------- */
649 GVArray::GVArray(const GVArray &other) = default;
650 
651 GVArray::GVArray(GVArray &&other) noexcept = default;
652 
654 {
655 }
656 
657 GVArray::GVArray(std::shared_ptr<const GVArrayImpl> impl) : GVArrayCommon(std::move(impl))
658 {
659 }
660 
662  const CPPType &type,
663  int64_t size,
664  const void *value)
665 {
666  if (type.is_trivial() && type.size() <= 16 && type.alignment() <= 8) {
667  this->emplace<GVArrayImpl_For_SmallTrivialSingleValue<16>>(type, size, value);
668  }
669  else {
670  this->emplace<GVArrayImpl_For_SingleValue>(type, size, value);
671  }
672 }
673 
674 GVArray GVArray::ForSingle(const CPPType &type, const int64_t size, const void *value)
675 {
676  return GVArray(varray_tag::single{}, type, size, value);
677 }
678 
679 GVArray GVArray::ForSingleRef(const CPPType &type, const int64_t size, const void *value)
680 {
681  return GVArray(varray_tag::single_ref{}, type, size, value);
682 }
683 
685 {
687 }
688 
690 {
691  return GVArray(varray_tag::span{}, span);
692 }
693 
695  protected:
697 
698  public:
700  : GVArrayImpl_For_GSpan(array.as_mutable_span()), array_(std::move(array))
701  {
702  }
703 };
704 
706 {
707  return GVArray::For<GVArrayImpl_For_GArray>(array);
708 }
709 
711 {
712  return GVArray::ForSpan(GSpan(type));
713 }
714 
716 {
717  const CommonVArrayInfo info = this->common_info();
718  if (info.type == CommonVArrayInfo::Type::Single) {
719  return GVArray::ForSingle(this->type(), slice.size(), info.data);
720  }
721  /* Need to check for ownership, because otherwise the referenced data can be destructed when
722  * #this is destructed. */
724  return GVArray::ForSpan(GSpan(this->type(), info.data, this->size()).slice(slice));
725  }
726  return GVArray::For<GVArrayImpl_For_SlicedGVArray>(*this, slice);
727 }
728 
730 {
731  this->copy_from(other);
732  return *this;
733 }
734 
736 {
737  this->move_from(std::move(other));
738  return *this;
739 }
740 
743 /* -------------------------------------------------------------------- */
747 GVMutableArray::GVMutableArray(const GVMutableArray &other) = default;
748 GVMutableArray::GVMutableArray(GVMutableArray &&other) noexcept = default;
749 
751 {
752 }
753 
754 GVMutableArray::GVMutableArray(std::shared_ptr<GVMutableArrayImpl> impl)
755  : GVArrayCommon(std::move(impl))
756 {
757 }
758 
760 {
761  return GVMutableArray::For<GVArrayImpl_For_GSpan_final>(span);
762 }
763 
764 GVMutableArray::operator GVArray() const &
765 {
766  GVArray varray;
767  varray.copy_from(*this);
768  return varray;
769 }
770 
771 GVMutableArray::operator GVArray() &&noexcept
772 {
773  GVArray varray;
774  varray.move_from(std::move(*this));
775  return varray;
776 }
777 
779 {
780  this->copy_from(other);
781  return *this;
782 }
783 
785 {
786  this->move_from(std::move(other));
787  return *this;
788 }
789 
791 {
792  return this->get_impl();
793 }
794 
795 void GVMutableArray::set_all(const void *src)
796 {
797  this->get_impl()->set_all(src);
798 }
799 
801 {
802  BLI_assert(this->is_span());
803  const CommonVArrayInfo info = impl_->common_info();
804  return GMutableSpan(this->type(), const_cast<void *>(info.data), this->size());
805 }
806 
809 CommonVArrayInfo GVArrayImpl_For_GSpan_final::common_info() const
810 {
812 }
813 
814 CommonVArrayInfo GVArrayImpl_For_SingleValueRef_final::common_info() const
815 {
816  return CommonVArrayInfo(CommonVArrayInfo::Type::Single, false, value_);
817 }
818 
819 } // namespace blender
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BUFFER_FOR_CPP_TYPE_VALUE(type, variable_name)
#define UNUSED(x)
#define POINTER_OFFSET(v, ofs)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
bool has_value() const
Definition: BLI_any.hh:249
const RealExtraInfo & extra_info() const
Definition: BLI_any.hh:330
void * get()
Definition: BLI_any.hh:288
bool is_trivial() const
void default_construct_n(void *ptr, int64_t n) const
void fill_assign_indices(const void *value, void *dst, IndexMask mask) const
void destruct_n(void *ptr, int64_t n) const
void fill_assign_n(const void *value, void *dst, int64_t n) const
void copy_assign_indices(const void *src, void *dst, IndexMask mask) const
void fill_construct_n(const void *value, void *dst, int64_t n) const
void copy_assign_n(const void *src, void *dst, int64_t n) const
void copy_construct_compressed(const void *src, void *dst, IndexMask mask) const
void copy_assign_compressed(const void *src, void *dst, IndexMask mask) const
void copy_construct(const void *src, void *dst) const
void destruct(void *ptr) const
int64_t size() const
void fill_construct_indices(const void *value, void *dst, IndexMask mask) const
int64_t alignment() const
void copy_assign(const void *src, void *dst) const
void move_construct(void *src, void *dst) const
const void * default_value() const
void relocate_assign(void *src, void *dst) const
void default_construct(void *ptr) const
void copy_construct_indices(const void *src, void *dst, IndexMask mask) const
const GVMutableArray & varray() const
GMutableVArraySpan & operator=(GMutableVArraySpan &&other)
GSpan slice(const int64_t start, int64_t size) const
const void * data_
const CPPType * type_
CommonVArrayInfo common_info() const
const GVArrayImpl * impl_from_storage() const
void copy_from(const GVArrayCommon &other)
const CPPType & type() const
void move_from(GVArrayCommon &&other) noexcept
void get_to_uninitialized(int64_t index, void *r_value) const
void materialize(void *dst) const
void get_internal_single_to_uninitialized(void *r_value) const
void materialize_to_uninitialized(void *dst) const
void get(int64_t index, void *r_value) const
IndexRange index_range() const
void materialize_compressed_to_uninitialized(IndexMask mask, void *dst) const
void materialize_compressed(IndexMask mask, void *dst) const
void get_internal_single(void *r_value) const
virtual void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override
CommonVArrayInfo common_info() const override
void set_by_move(int64_t index, void *value) override
void get_to_uninitialized(int64_t index, void *r_value) const override
virtual void materialize(const IndexMask mask, void *dst) const override
void set_by_relocate(int64_t index, void *value) override
virtual void materialize_compressed(const IndexMask mask, void *dst) const override
virtual void materialize_to_uninitialized(const IndexMask mask, void *dst) const override
void get(int64_t index, void *r_value) const override
void set_by_copy(int64_t index, const void *value) override
void materialize_to_uninitialized(const IndexMask mask, void *dst) const override
void get(const int64_t index, void *r_value) const override
void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override
void materialize_compressed(const IndexMask mask, void *dst) const override
void get_to_uninitialized(const int64_t index, void *r_value) const override
CommonVArrayInfo common_info() const override
void materialize(const IndexMask mask, void *dst) const override
GVArrayImpl_For_SingleValue(const CPPType &type, const int64_t size, const void *value)
CommonVArrayInfo common_info() const override
void get(const int64_t index, void *r_value) const override
void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override
GVArrayImpl_For_SlicedGVArray(GVArray varray, const IndexRange slice)
void get_to_uninitialized(const int64_t index, void *r_value) const override
GVArrayImpl_For_SmallTrivialSingleValue(const CPPType &type, const int64_t size, const void *value)
virtual void materialize_compressed_to_uninitialized(IndexMask mask, void *dst) const
virtual void get_to_uninitialized(int64_t index, void *r_value) const =0
virtual void materialize_compressed(IndexMask mask, void *dst) const
virtual void materialize(const IndexMask mask, void *dst) const
virtual void materialize_to_uninitialized(const IndexMask mask, void *dst) const
virtual void get(int64_t index, void *r_value) const
virtual bool try_assign_VArray(void *varray) const
virtual CommonVArrayInfo common_info() const
const CPPType & type() const
GVArraySpan & operator=(GVArraySpan &&other)
GVArray slice(IndexRange slice) const
static GVArray ForEmpty(const CPPType &type)
static GVArray ForGArray(GArray<> array)
GVArray()=default
static GVArray ForSingleDefault(const CPPType &type, int64_t size)
GVArray & operator=(const GVArray &other)
static GVArray ForSingleRef(const CPPType &type, int64_t size, const void *value)
static GVArray ForSpan(GSpan span)
static GVArray ForSingle(const CPPType &type, int64_t size, const void *value)
virtual bool try_assign_VMutableArray(void *varray) const
virtual void set_all(const void *src)
virtual void set_by_copy(int64_t index, const void *value)
virtual void set_by_relocate(int64_t index, void *value)
virtual void set_by_move(int64_t index, void *value)=0
void set_all(const void *src)
void set_by_copy(int64_t index, const void *value)
GVMutableArrayImpl * get_implementation() const
GMutableSpan get_internal_span() const
GVMutableArray & operator=(const GVMutableArray &other)
void fill(const void *value)
static GVMutableArray ForSpan(GMutableSpan span)
constexpr int64_t one_after_last() const
constexpr int64_t size() const
constexpr int64_t start() const
Span< T > as_span() const
Definition: BLI_vector.hh:325
SyclQueue void void * src
ccl_global float * buffer
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str)
Definition: mallocn.c:35
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static IOCIOImpl * impl
Definition: ocio_capi.cc:8
__int64 int64_t
Definition: stdint.h:89