Blender  V3.3
COM_BufferArea.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2021 Blender Foundation. */
3 
4 #pragma once
5 
6 #include "BLI_assert.h"
7 #include "BLI_rect.h"
8 #include <iterator>
9 
10 namespace blender::compositor {
11 
12 /* Forward declarations. */
13 template<typename T> class BufferAreaIterator;
14 
18 template<typename T> class BufferArea : rcti {
19  public:
22 
23  private:
24  T *buffer_;
25  /* Number of elements in a buffer row. */
26  int buffer_width_;
27  /* Buffer element stride. */
28  int elem_stride_;
29 
30  public:
31  constexpr BufferArea() = default;
32 
36  constexpr BufferArea(T *buffer, int buffer_width, const rcti &area, int elem_stride = 1)
37  : rcti(area), buffer_(buffer), buffer_width_(buffer_width), elem_stride_(elem_stride)
38  {
39  }
40 
44  constexpr BufferArea(T *buffer, int buffer_width, int buffer_height, int elem_stride = 1)
45  : buffer_(buffer), buffer_width_(buffer_width), elem_stride_(elem_stride)
46  {
47  BLI_rcti_init(this, 0, buffer_width, 0, buffer_height);
48  }
49 
50  constexpr friend bool operator==(const BufferArea &a, const BufferArea &b)
51  {
52  return a.buffer_ == b.buffer_ && BLI_rcti_compare(&a, &b) && a.elem_stride_ == b.elem_stride_;
53  }
54 
55  constexpr const rcti &get_rect() const
56  {
57  return *this;
58  }
59 
63  constexpr int width() const
64  {
65  return BLI_rcti_size_x(this);
66  }
67 
71  constexpr int height() const
72  {
73  return BLI_rcti_size_y(this);
74  }
75 
76  constexpr Iterator begin()
77  {
78  return begin_iterator<Iterator>();
79  }
80 
81  constexpr Iterator end()
82  {
83  return end_iterator<Iterator>();
84  }
85 
86  constexpr ConstIterator begin() const
87  {
88  return begin_iterator<ConstIterator>();
89  }
90 
91  constexpr ConstIterator end() const
92  {
93  return end_iterator<ConstIterator>();
94  }
95 
96  private:
97  template<typename TIterator> constexpr TIterator begin_iterator() const
98  {
99  T *end_ptr = get_end_ptr();
100  if (elem_stride_ == 0) {
101  /* Iterate a single element. */
102  return TIterator(buffer_, end_ptr, 1, 1, 1);
103  }
104 
105  T *begin_ptr = buffer_ + (intptr_t)this->ymin * buffer_width_ * elem_stride_ +
106  (intptr_t)this->xmin * elem_stride_;
107  return TIterator(begin_ptr, end_ptr, buffer_width_, BLI_rcti_size_x(this), elem_stride_);
108  }
109 
110  template<typename TIterator> constexpr TIterator end_iterator() const
111  {
112  T *end_ptr = get_end_ptr();
113  if (elem_stride_ == 0) {
114  /* Iterate a single element. */
115  return TIterator(end_ptr, end_ptr, 1, 1, 1);
116  }
117 
118  return TIterator(end_ptr, end_ptr, buffer_width_, BLI_rcti_size_x(this), elem_stride_);
119  }
120 
121  T *get_end_ptr() const
122  {
123  if (elem_stride_ == 0) {
124  return buffer_ + 1;
125  }
126  return buffer_ + (intptr_t)(this->ymax - 1) * buffer_width_ * elem_stride_ +
127  (intptr_t)this->xmax * elem_stride_;
128  }
129 };
130 
131 template<typename T> class BufferAreaIterator {
132  public:
133  using iterator_category = std::input_iterator_tag;
134  using value_type = T *;
135  using pointer = T *const *;
136  using reference = T *const &;
137  using difference_type = std::ptrdiff_t;
138 
139  private:
140  int elem_stride_;
141  int row_stride_;
142  /* Stride between a row end and the next row start. */
143  int rows_gap_;
144  T *current_;
145  const T *row_end_;
146  const T *end_;
147 
148  public:
149  constexpr BufferAreaIterator() = default;
150 
152  T *current, const T *end, int buffer_width, int area_width, int elem_stride = 1)
153  : elem_stride_(elem_stride),
154  row_stride_(buffer_width * elem_stride),
155  rows_gap_(row_stride_ - area_width * elem_stride),
156  current_(current),
157  row_end_(current + area_width * elem_stride),
158  end_(end)
159  {
160  }
161 
163  {
164  current_ += elem_stride_;
165  BLI_assert(current_ <= row_end_);
166  if (current_ == row_end_) {
167  BLI_assert(current_ <= end_);
168  if (current_ == end_) {
169  return *this;
170  }
171  current_ += rows_gap_;
172  row_end_ += row_stride_;
173  }
174  return *this;
175  }
176 
177  constexpr BufferAreaIterator operator++(int) const
178  {
179  BufferAreaIterator copied_iterator = *this;
180  ++copied_iterator;
181  return copied_iterator;
182  }
183 
184  constexpr friend bool operator!=(const BufferAreaIterator &a, const BufferAreaIterator &b)
185  {
186  return a.current_ != b.current_;
187  }
188 
189  constexpr friend bool operator==(const BufferAreaIterator &a, const BufferAreaIterator &b)
190  {
191  return a.current_ == b.current_;
192  }
193 
194  constexpr T *operator*() const
195  {
196  return current_;
197  }
198 };
199 
200 } // namespace blender::compositor
#define BLI_assert(a)
Definition: BLI_assert.h:46
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
bool BLI_rcti_compare(const struct rcti *rect_a, const struct rcti *rect_b)
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition: rct.c:417
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
constexpr friend bool operator==(const BufferAreaIterator &a, const BufferAreaIterator &b)
constexpr BufferAreaIterator(T *current, const T *end, int buffer_width, int area_width, int elem_stride=1)
constexpr BufferAreaIterator operator++(int) const
constexpr BufferAreaIterator & operator++()
std::input_iterator_tag iterator_category
constexpr friend bool operator!=(const BufferAreaIterator &a, const BufferAreaIterator &b)
constexpr BufferArea(T *buffer, int buffer_width, const rcti &area, int elem_stride=1)
constexpr int height() const
constexpr const rcti & get_rect() const
constexpr Iterator begin()
constexpr BufferArea(T *buffer, int buffer_width, int buffer_height, int elem_stride=1)
constexpr ConstIterator begin() const
constexpr BufferArea()=default
constexpr friend bool operator==(const BufferArea &a, const BufferArea &b)
constexpr int width() const
constexpr ConstIterator end() const
ccl_global float * buffer
#define T
static unsigned a[3]
Definition: RandGen.cpp:78
static void area(int d1, int d2, int e1, int e2, float weights[2])
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
_W64 int intptr_t
Definition: stdint.h:118
int ymin
Definition: DNA_vec_types.h:64
int ymax
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
int xmax
Definition: DNA_vec_types.h:63