Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: cc/base/pyramid_sequence.h

Issue 2067213002: cc: Implement tile iteration order based on pyramid sequence. [old] Base URL: https://chromium.googlesource.com/chromium/src.git@tiling_data_fix
Patch Set: for review Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CC_BASE_PYRAMID_SEQUENCE_H_
6 #define CC_BASE_PYRAMID_SEQUENCE_H_
7
8 #include <list>
9 #include <vector>
10
11 #include "base/logging.h"
12 #include "cc/base/cc_export.h"
13
14 namespace cc {
15
16 // Triangular sequence is the representation of numbers in triangular form. This
17 // takes initial |interval| (start <= number <= end), and inflates that interval
18 // by the |levels| given, keeping the interval limit defined by the
19 // |interval_inflate_limit|.
20 //
21 // e.g. With intial interval of [3, 4] and levels 4, the triagular sequence
22 // would be as given below.
23 // 3 4 (level 1)
24 // 2 3 4 5 (level 2)
25 // 1 2 3 4 5 6 (level 3)
26 // 0 1 2 3 4 5 6 7 (level 4)
vmpstr 2016/07/19 20:28:28 What would level 5 look like here?
prashant.n 2016/07/20 03:10:49 -1 0 1 2 3 4 5 6 7 8 The inflation of intervals h
27 //
28 // With inflate limit of interval [2, 5] defined for the above example, the
29 // sequence would be as given below.
30 // 3 4
31 // 2 3 4 5
32 // 2 3 4 5
33 // 2 3 4 5
34 //
35 // With inflate limit of interval [3, 10] defined for the above example, the
36 // sequence would be as given below.
37 // 3 4
38 // 3 4 5
39 // 3 4 5 6
40 // 3 4 5 6 7
41 // The triangular sequence can be of four different types as given below.
42 // 1. FORWARD - start <= end as depicted in above example.
43 // 2. BACKWARD - start >= end, e.g. initial interval [4, 3]
44 // 4 3
45 // 5 4 3 2
46 // 3. DIAGONAL_FORWARD - start == end, in this case inflation happens in
47 // positive direction.
48 // e.g. 2, 3, 4, 5
49 // 4. DIAGONAL_BACKWARD - start == end, in this case inflation happens in
50 // negative direction.
51 // e.g. 5, 4, 3, 2
52 class CC_EXPORT TriangularSequence {
vmpstr 2016/07/19 20:28:28 I think this class is conflating too many settings
prashant.n 2016/07/20 03:10:49 This is to cater different portions of the pyramid
prashant.n 2016/07/20 03:53:10 For this I'll check if we can have container <-> i
53 public:
54 enum class Type : uint16_t {
55 FORWARD,
56 BACKWARD,
57 DIAGONAL_FORWARD,
58 DIAGONAL_BACKWARD
59 };
60
61 // Interval representing start and end, mathematical interval [start, end].
62 struct Interval {
63 Interval(int start, int end) : start(start), end(end) {}
64 Interval(const Interval& other) = default;
vmpstr 2016/07/19 20:28:28 You don't need to specify copy/move operations her
prashant.n 2016/07/20 03:10:49 When I tested on Windows (Visual Studio 2013) it w
65 Interval(Interval&& other) = default;
66 Interval& operator=(const Interval& other) = default;
67 Interval& operator=(Interval&& other) = default;
68
69 int start;
70 int end;
71 };
72
73 // |name| - Name for the sequence.
74 // |type| - Type of the sequence.
75 // |interval| - Initial interval.
76 // |interval_inflate_limit| - Inflating limit for interval.
77 // |levels| - Number of times inflation should happen.
78 // |levels_to_skip| - Number of levels to skip. The inital interval is
79 // inflated to this value, so that the interval to start the sequence is
80 // pointed to the required level.
81 // |reverse| - If true the initial interval is inflated to the last level and
82 // sequence is continued from |levels| to |levels_to_skip|.
83 TriangularSequence(std::string&& name,
84 Type type,
85 Interval&& interval,
86 Interval&& interval_inflate_limit,
87 int levels,
88 int levels_to_skip,
89 bool reverse);
90 TriangularSequence(const TriangularSequence& other);
91 TriangularSequence(TriangularSequence&& other);
92 ~TriangularSequence();
93
94 TriangularSequence& operator=(const TriangularSequence& other);
95 TriangularSequence& operator=(TriangularSequence&& other);
96
97 // Returns whether the sequence at the current level is overflowing the limits
98 // of the current interval.
99 bool is_within_bounds() { return within_bounds_; }
100
101 int GetInitialIntervalSpan();
102
103 // Get the current sequence number, if the number has overflown the current
104 // level's interval, then interval is inflated and number starting at the next
105 // interval is returned. If all levels have been traversed, then it returns
106 // last number in the sequence.
107 int GetCurrentSequenceNumber();
108 // Same like above, but in reverse direction.
vmpstr 2016/07/19 20:28:28 This is not clear at all. GetCurrentSequenceNumber
prashant.n 2016/07/20 03:10:49 Hmm. I'll write simple functions having more appro
109 int GetReverseCurrentSequenceNumber();
110
111 // Advances the sequence number to the next in the current interval. If number
112 // overflows the interval, then |within_bounds_| is set to false.
113 void Advance();
114
115 private:
116 using InflateFn = void (TriangularSequence::*)(int levels);
117 using IsWithinBoundsFn = bool (TriangularSequence::*)();
118
119 void Init(Type type);
120 void Reset();
121
122 // Interval inflating functions for different TriangularSequence types.
123 void InflateForward(int levels);
124 void InflateBackward(int levels);
125 void InflateDiagonalForward(int levels);
126 void InflateDiagonalBackward(int levels);
127
128 // Functions for checking the bounds for different TriangularSequence types.
129 bool IsWithinBoundsForward();
130 bool IsWithinBoundsBackward();
131 bool IsWithinBoundsDiagonal();
132
133 std::string name_;
134 Type type_;
135 Interval interval_;
136 Interval interval_inflate_limit_;
137 Interval initial_interval_;
138 int levels_;
139 int levels_traversed_;
140 int levels_limit_;
141 bool reverse_;
142 bool within_bounds_;
143 int current_sequence_number_;
144 int step_;
145
146 InflateFn inflate_;
147 IsWithinBoundsFn is_within_bounds_;
148 };
149
150 // This class implements the 2D sequence which uses two triangular sequences,
151 // one for traversing the actual sequence and other for computing the number of
152 // levels for the traversal sequence.
153 //
154 // LevelDistance means each level has some length value associated with it. The
155 // distance is distance from the viewport or rect of interest. If there are 5
156 // levels and distance is 10, then the levels would have distances as given
157 // below. 0, 10, 20, 30, 40. The first level starts with 0, so as to represent
158 // the minimum distance for that level. The distances are stored in sorted
159 // order in the vector, so that distance at front is minimum and distance at
160 // back is maximum. The layout of the level distance vector for the example
161 // would be (0, 0), (1, 10), (2, 20), (3, 30), (4, 40).
162 //
163 // e.g. If traversal sequence is [3, 4], number of levels is 3 and distance is
164 // 10, then layout of the level distance sequence would be as given below.
165 //
166 // x 0 1 2 3 4 5 6 7
167 // y.----------------
168 // 0| . . . 3 4 . . . (level 1, distance 0)
169 // 1| . . 2 3 4 5 . . (level 2, distance 10)
170 // 2| . 1 2 3 4 5 6 . (level 3, distance 20)
171 // 3| . . . . . . . .
172 // 4| . . . . . . . .
173 //
174 // When the above sequence is iterated then the indices output would be as given
175 // below.
176 // (3, 0), (4, 0) (level 1)
177 // (2, 1), (3, 1), (4, 1), (5, 1), (level 2)
178 // (1, 2), (2, 2), (3, 2), (4, 2), (5, 2), (6, 2) (level 3)
179 // At each level change, this sequence conveys that level has changed.
180 class CC_EXPORT LevelDistanceSequence {
181 public:
182 typedef std::list<LevelDistanceSequence> List;
183 typedef List::iterator Iterator;
184 typedef List::reverse_iterator ReverseIterator;
185
186 LevelDistanceSequence();
187 // If |reverse| is true, then |traversal_sequence| is iterated from the
188 // interval at farthest level to the initial interval. If |swapped| is false
189 // then the sequence numbers in |traversal_sequence| represent the x index and
190 // sequence numbers in |level_sequence| represent the y index, otherwise vice
191 // versa.
192 LevelDistanceSequence(TriangularSequence&& traversal_sequence,
193 TriangularSequence&& level_sequence,
194 bool swapped,
195 int levels_to_skip,
196 int levels_delta,
197 int distance,
198 bool reverse);
199 LevelDistanceSequence(const LevelDistanceSequence& other);
200 LevelDistanceSequence(LevelDistanceSequence&& other);
201 ~LevelDistanceSequence();
202
203 LevelDistanceSequence& operator=(const LevelDistanceSequence& other);
204 LevelDistanceSequence& operator=(LevelDistanceSequence&& other);
205
206 // Return true if this sequence is valid or not.
207 bool IsValid() const { return !level_distances_.empty(); }
208
209 // Gets current indices.
210 int GetCurrentIndexX() const;
211 int GetCurrentIndexY() const;
212
213 // Get minimum/maximum distance.
214 int GetMinimumDistance() const;
215 int GetMaximumDistance() const;
216
217 // Advances or reverse-advances the |traversal_sequence|. When the interval is
218 // traversed fully, then this function return false for indicating the current
219 // level in |traversal_sequence| has been finished.
220 bool Advance();
221 bool ReverseAdvance();
222
223 private:
224 struct LevelDistance {
225 LevelDistance(int level, int distance) : level(level), distance(distance) {}
226
227 int level;
228 int distance;
229 };
230
231 void Reset();
232
233 TriangularSequence traversal_sequence_;
234 bool swapped_;
235 bool reverse_;
236 int current_sequence_index_;
237 int current_level_index_;
238 std::vector<LevelDistance> level_distances_;
239 };
240
241 // The pyramid sequence is list of 8 level distance sequences, one for each of
242 // the directions considered counter-clockwise or clockwise. The actual order
243 // of level distance sequences is computed by the direction in which coverage is
244 // required. (See GetCoverageDirectionSequenceForDirections() for more details.)
245 // The ideal pyramid sequence is as given below where it has all 8 directions.
246 //
247 // 2 T T T T T 1
248 // L 2 T T T 1 R
249 // L L 2 T 1 R R
250 // L L L * R R R
251 // L L 3 B 4 R R
252 // L 3 B B B 4 R
253 // 3 B B B B B 4
254 //
255 // The different level distance sequences for the above pyramid sequence is
256 // shown below.
257 //
258 // (T = top)
259 // |
260 // (2 = top-left) T T T T T (1 = top-right)
261 // 2 T T T 1
262 // L 2 T 1 R
263 // L L 2 1 R R
264 // (L = left) --> L L L * R R R <-- (R = right)
265 // L L 3 4 R R
266 // L 3 B 4 R
267 // 3 B B B 4
268 // (3 = bottom-left) B B B B B (4 = bottom-right)
269 // |
270 // (B = bottom)
271 //
272 // This sequence iterates over all the underlined level distance sequences level
273 // by level in increasing or decreasing order of distances. The increasing order
274 // of distance is called as TopDownPyramidSequence, while the other is called as
275 // BottomUpPyramidSequence. The iteration sequence generated by top down pyramid
276 // sequence is as given below. (Iteration is considered counter-clockwise.)
277 //
278 // x 0 1 2 3 4 5 6
279 // y.---------------------
280 // 0| 36 35 34 33 32 31 30
281 // 1| 37 16 15 14 13 12 29
282 // 2| 38 17 4 3 2 11 28
283 // 3| 39 18 5 * 1 10 27
284 // 4| 40 19 6 7 8 9 26
285 // 5| 41 20 21 22 23 24 25
286 // 6| 42 43 44 45 46 47 48
287 //
288 // The iteration sequence generated by bottom up pyramid sequence is as given
289 // below. (Iteration is considered clockwise.)
290 //
291 // x 0 1 2 3 4 5 6
292 // y.----------------------
293 // 0| 13 14 15 16 17 18 19
294 // 1| 12 33 34 35 36 37 20
295 // 2| 11 32 45 46 47 38 21
296 // 3| 10 31 44 * 48 39 22
297 // 4| 9 30 43 42 41 40 23
298 // 5| 8 29 28 27 26 25 24
299 // 6| 7 6 5 4 3 2 1
300 class CC_EXPORT PyramidSequence {
301 public:
302 explicit PyramidSequence(bool reverse);
303 PyramidSequence(const PyramidSequence& other);
304 PyramidSequence(PyramidSequence&& other);
305 virtual ~PyramidSequence();
306
307 PyramidSequence& operator=(const PyramidSequence& other);
308 PyramidSequence& operator=(PyramidSequence&& other);
309
310 virtual void Init(int around_left,
311 int around_right,
312 int around_top,
313 int around_bottom,
314 int consider_left,
315 int consider_right,
316 int consider_top,
317 int consider_bottom,
318 int ignore_left,
319 int ignore_right,
320 int ignore_top,
321 int ignore_bottom,
322 int width,
323 int height);
324 bool IsTraversed();
325
326 virtual void Advance() = 0;
327
328 void UpdateCurrent();
329 int GetCurrentIndexX() const { return index_x_; }
330 int GetCurrentIndexY() const { return index_y_; }
331
332 protected:
333 virtual LevelDistanceSequence* GetNextLevelDistanceSequence() = 0;
334
335 void EmplaceAt(int position, LevelDistanceSequence&& level_distance_sequence);
336 bool InConsiderRect() const;
337 bool InIgnoreRect() const;
338 void RemoveEmptyLevelDistanceSequences();
339
340 bool reverse_;
341 LevelDistanceSequence* current_level_distance_sequence_;
342 int consider_left_;
343 int consider_right_;
344 int consider_top_;
345 int consider_bottom_;
346 int ignore_left_;
347 int ignore_right_;
348 int ignore_top_;
349 int ignore_bottom_;
350 int index_x_;
351 int index_y_;
352 LevelDistanceSequence::List level_distance_sequences_;
353 };
354
355 class CC_EXPORT TopDownPyramidSequence : public PyramidSequence {
356 public:
357 TopDownPyramidSequence();
358 TopDownPyramidSequence(const TopDownPyramidSequence& other);
359 TopDownPyramidSequence(TopDownPyramidSequence&& other);
360 ~TopDownPyramidSequence() override;
361
362 TopDownPyramidSequence& operator=(const TopDownPyramidSequence& other);
363 TopDownPyramidSequence& operator=(TopDownPyramidSequence&& other);
364
365 void Advance() override;
366
367 private:
368 LevelDistanceSequence* GetNextLevelDistanceSequence() override;
369 };
370
371 class CC_EXPORT BottomUpPyramidSequence : public PyramidSequence {
372 public:
373 BottomUpPyramidSequence();
374 BottomUpPyramidSequence(const BottomUpPyramidSequence& other);
375 BottomUpPyramidSequence(BottomUpPyramidSequence&& other);
376 ~BottomUpPyramidSequence() override;
377
378 BottomUpPyramidSequence& operator=(const BottomUpPyramidSequence& other);
379 BottomUpPyramidSequence& operator=(BottomUpPyramidSequence&& other);
380
381 void Advance() override;
382
383 private:
384 LevelDistanceSequence* GetNextLevelDistanceSequence() override;
385 };
386
387 } // namespace cc
388
389 #endif // CC_BASE_PYRAMID_SEQUENCE_H_
OLDNEW
« no previous file with comments | « cc/base/BUILD.gn ('k') | cc/base/pyramid_sequence.cc » ('j') | cc/base/pyramid_sequence.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698