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

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

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: spiral coverage sequence Created 4 years, 4 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 #include "cc/base/pyramid_sequence.h"
6
7 #include <algorithm>
8 #include <string>
9
10 namespace cc {
11
12 namespace {
13
14 int ClampNumberInForwardInterval(int number, int start_limit, int end_limit) {
15 DCHECK_LE(start_limit, end_limit);
16 if (number < start_limit)
17 return start_limit;
18 if (number > end_limit)
19 return end_limit;
20 return number;
21 }
22
23 int ClampNumberInBackwardInterval(int number, int start_limit, int end_limit) {
24 DCHECK_GE(start_limit, end_limit);
25 if (number > start_limit)
26 return start_limit;
27 if (number < end_limit)
28 return end_limit;
29 return number;
30 }
31
32 int LevelsToSkipAlongDirection(int levels) {
33 return levels > 0 ? levels : 0;
34 }
35
36 int LevelsToSkipPerpendicularToDirection(int levels) {
37 return levels >= 0 ? levels + 1 : 0;
38 }
39
40 enum class CoverageDirection : uint8_t {
41 RIGHT = 0,
42 TOP_RIGHT,
43 TOP,
44 TOP_LEFT,
45 LEFT,
46 BOTTOM_LEFT,
47 BOTTOM,
48 BOTTOM_RIGHT
49 };
50
51 // The pyramid sequence covers following 8 directions while iterating.
52 // TL T TR
53 // L * R
54 // BL B BR
55 //
56 // where -
57 // R = right
58 // TR = top right
59 // T = top
60 // TL = top left
61 // L = left
62 // BL = bottom left
63 // B = bottom
64 // BR = bottom right
65 //
66 // The following function returns the spiral order {R, TR, T, TL, L, BL, B, BR}.
67 CoverageDirection* GetCoverageDirectionSequence() {
68 static CoverageDirection right_top_right[8] = {
69 CoverageDirection::RIGHT, CoverageDirection::TOP_RIGHT,
70 CoverageDirection::TOP, CoverageDirection::TOP_LEFT,
71 CoverageDirection::LEFT, CoverageDirection::BOTTOM_LEFT,
72 CoverageDirection::BOTTOM, CoverageDirection::BOTTOM_RIGHT};
73 return right_top_right;
74 }
75
76 int GetPositionForDirection(CoverageDirection* positions,
77 CoverageDirection direction) {
78 for (int i = 0; i < 8; ++i) {
79 if (positions[i] == direction)
80 return i;
81 }
82
83 NOTREACHED();
84 return -1;
85 }
86
87 } // namespace
88
89 // Interval implementation.
90 Interval::Interval(Type type,
91 int start,
92 int end,
93 int start_inflate_limit,
94 int end_inflate_limit,
95 bool reverse_order)
96 : start_(start),
97 end_(end),
98 initial_start_(start),
99 initial_end_(end),
100 start_inflate_limit_(start_inflate_limit),
101 end_inflate_limit_(end_inflate_limit),
102 reverse_order_(reverse_order),
103 within_bounds_(true),
104 inflate_to_level_ptr_(nullptr),
105 is_within_bounds_ptr_(nullptr) {
106 Init(type);
107 Reset();
108 }
109
110 Interval::Interval(const Interval& other) = default;
111
112 Interval::Interval(Interval&& other) = default;
113
114 Interval::~Interval() {
115 inflate_to_level_ptr_ = nullptr;
116 is_within_bounds_ptr_ = nullptr;
117 }
118
119 Interval& Interval::operator=(const Interval& other) = default;
120
121 Interval& Interval::operator=(Interval&& other) = default;
122
123 Interval& Interval::operator++() {
124 DCHECK(is_within_bounds_ptr_);
125 current_index_ += step_;
126 within_bounds_ = (this->*is_within_bounds_ptr_)();
127
128 return *this;
129 }
130
131 void Interval::InflateToLevel(int level) {
132 DCHECK(inflate_to_level_ptr_);
133 (this->*inflate_to_level_ptr_)(level);
134 }
135
136 int Interval::GetSpan() {
137 return std::abs(end_ - start_) + 1;
138 }
139
140 void Interval::Init(Interval::Type type) {
141 switch (type) {
142 case Interval::Type::FORWARD:
143 inflate_to_level_ptr_ = &Interval::InflateToLevelForward;
144 is_within_bounds_ptr_ = &Interval::IsWithinBoundsForward;
145 step_ = reverse_order_ ? -1 : 1;
146 break;
147 case Interval::Type::BACKWARD:
148 inflate_to_level_ptr_ = &Interval::InflateToLevelBackward;
149 is_within_bounds_ptr_ = &Interval::IsWithinBoundsBackward;
150 step_ = reverse_order_ ? 1 : -1;
151 break;
152 case Interval::Type::DIAGONAL_FORWARD:
153 DCHECK_EQ(start_, end_);
154 inflate_to_level_ptr_ = &Interval::InflateToLevelDiagonalForward;
155 is_within_bounds_ptr_ = &Interval::IsWithinBoundsDiagonal;
156 step_ = reverse_order_ ? -1 : 1;
157 break;
158 case Interval::Type::DIAGONAL_BACKWARD:
159 DCHECK_EQ(start_, end_);
160 inflate_to_level_ptr_ = &Interval::InflateToLevelDiagonalBackward;
161 is_within_bounds_ptr_ = &Interval::IsWithinBoundsDiagonal;
162 step_ = reverse_order_ ? 1 : -1;
163 break;
164 }
165 }
166
167 void Interval::Reset() {
168 current_index_ = reverse_order_ ? end_ : start_;
169 within_bounds_ = true;
170 }
171
172 void Interval::InflateToLevelForward(int level) {
173 start_ = initial_start_ - level;
174 end_ = initial_end_ + level;
175
176 start_ = ClampNumberInForwardInterval(start_, start_inflate_limit_,
177 end_inflate_limit_);
178 end_ = ClampNumberInForwardInterval(end_, start_inflate_limit_,
179 end_inflate_limit_);
180
181 Reset();
182 }
183
184 void Interval::InflateToLevelBackward(int level) {
185 start_ = initial_start_ + level;
186 end_ = initial_end_ - level;
187 start_ = ClampNumberInBackwardInterval(start_, start_inflate_limit_,
188 end_inflate_limit_);
189 end_ = ClampNumberInBackwardInterval(end_, start_inflate_limit_,
190 end_inflate_limit_);
191
192 Reset();
193 }
194
195 void Interval::InflateToLevelDiagonalForward(int level) {
196 start_ = initial_start_ + level;
197 end_ = initial_end_ + level;
198
199 Reset();
200 }
201
202 void Interval::InflateToLevelDiagonalBackward(int level) {
203 start_ = initial_start_ - level;
204 end_ = initial_end_ - level;
205
206 Reset();
207 }
208
209 bool Interval::IsWithinBoundsForward() {
210 DCHECK(reverse_order_ ? current_index_ <= end_ : current_index_ >= start_);
211
212 if (start_ == end_ ||
213 (reverse_order_ ? current_index_ < start_ : current_index_ > end_))
214 return false;
215
216 return true;
217 }
218
219 bool Interval::IsWithinBoundsBackward() {
220 DCHECK(reverse_order_ ? current_index_ >= end_ : current_index_ <= start_);
221
222 if (start_ == end_ ||
223 (reverse_order_ ? current_index_ > start_ : current_index_ < end_))
224 return false;
225
226 return true;
227 }
228
229 bool Interval::IsWithinBoundsDiagonal() {
230 DCHECK_EQ(start_, end_);
231 if (current_index_ != start_)
232 return false;
233
234 return true;
235 }
236
237 // TriangularSequence implementation.
238 TriangularSequence::TriangularSequence()
239 : name_(std::string("dummy")),
240 traversal_interval_(Interval::Type::FORWARD, 0, 0, 0, 0, false),
241 swapped_(false),
242 reverse_order_(false),
243 current_level_index_(-1) {}
244
245 TriangularSequence::TriangularSequence(std::string&& name,
246 Interval&& traversal_interval,
247 Interval&& level_interval,
248 bool swapped,
249 int levels_to_skip,
250 int distance,
251 bool reverse_order)
252 : name_(std::move(name)),
253 traversal_interval_(std::move(traversal_interval)),
254 swapped_(swapped),
255 reverse_order_(reverse_order) {
256 int span = level_interval.GetSpan();
257 DCHECK_GE(span, levels_to_skip);
258
259 // Skip |levels_to_skip| levels in level interval.
260 for (int i = 0; i < levels_to_skip; ++i)
261 ++level_interval;
262
263 for (int i = levels_to_skip; i < span; ++i) {
264 level_distances_.push_back(
265 LevelDistance(i, level_interval.index(), distance * i));
266 ++level_interval;
267 }
268
269 UpdateCurrent();
270 }
271
272 TriangularSequence::TriangularSequence(const TriangularSequence& other) =
273 default;
274
275 TriangularSequence::TriangularSequence(TriangularSequence&& other) = default;
276
277 TriangularSequence::~TriangularSequence() {
278 level_distances_.clear();
279 }
280
281 TriangularSequence& TriangularSequence::operator=(
282 const TriangularSequence& other) = default;
283
284 TriangularSequence& TriangularSequence::operator=(TriangularSequence&& other) =
285 default;
286
287 TriangularSequence& TriangularSequence::operator++() {
288 Advance();
289 UpdateCurrent();
290
291 return *this;
292 }
293
294 int TriangularSequence::GetMinimumDistance() const {
295 DCHECK(!level_distances_.empty());
296 return level_distances_.front().distance;
297 }
298
299 int TriangularSequence::GetMaximumDistance() const {
300 DCHECK(!level_distances_.empty());
301 return level_distances_.back().distance;
302 }
303
304 void TriangularSequence::Advance() {
305 if (!*this)
306 return;
307
308 if (reverse_order_)
309 level_distances_.erase(level_distances_.end() - 1);
310 else
311 level_distances_.erase(level_distances_.begin());
312 }
313
314 void TriangularSequence::UpdateCurrent() {
315 if (!*this)
316 return;
317
318 if (reverse_order_) {
319 current_level_index_ = level_distances_.back().level_index;
320 traversal_interval_.InflateToLevel(level_distances_.back().interval_level);
321 } else {
322 current_level_index_ = level_distances_.front().level_index;
323 traversal_interval_.InflateToLevel(level_distances_.front().interval_level);
324 }
325 }
326
327 // PyramidSequence implementation.
328 PyramidSequence::PyramidSequence(bool reverse_order)
329 : reverse_order_(reverse_order),
330 current_triangular_sequence_(nullptr),
331 index_x_(-1),
332 index_y_(-1) {}
333
334 PyramidSequence::PyramidSequence(const PyramidSequence& other) = default;
335
336 PyramidSequence::PyramidSequence(PyramidSequence&& other) = default;
337
338 PyramidSequence::~PyramidSequence() {
339 triangular_sequences_.clear();
340 current_triangular_sequence_ = nullptr;
341 }
342
343 PyramidSequence& PyramidSequence::operator=(const PyramidSequence& other) =
344 default;
345
346 PyramidSequence& PyramidSequence::operator=(PyramidSequence&& other) = default;
347
348 void PyramidSequence::Init(int around_left,
349 int around_right,
350 int around_top,
351 int around_bottom,
352 int consider_left,
353 int consider_right,
354 int consider_top,
355 int consider_bottom,
356 int ignore_left,
357 int ignore_right,
358 int ignore_top,
359 int ignore_bottom,
360 int width,
361 int height) {
362 consider_left_ = consider_left;
363 consider_right_ = consider_right;
364 consider_top_ = consider_top;
365 consider_bottom_ = consider_bottom;
366 ignore_left_ = ignore_left;
367 ignore_right_ = ignore_right;
368 ignore_top_ = ignore_top;
369 ignore_bottom_ = ignore_bottom;
370
371 int left_levels = around_left - consider_left + 1;
372 int right_levels = consider_right - around_right + 1;
373 int top_levels = around_top - consider_top + 1;
374 int bottom_levels = consider_bottom - around_bottom + 1;
375
376 int skip_left_levels = around_left - consider_right;
377 int skip_right_levels = consider_left - around_right;
378 int skip_top_levels = around_top - consider_bottom;
379 int skip_bottom_levels = consider_top - around_bottom;
380
381 int skip_left_levels_perp =
382 LevelsToSkipPerpendicularToDirection(skip_left_levels);
383 int skip_right_levels_perp =
384 LevelsToSkipPerpendicularToDirection(skip_right_levels);
385 int skip_top_levels_perp =
386 LevelsToSkipPerpendicularToDirection(skip_top_levels);
387 int skip_bottom_levels_perp =
388 LevelsToSkipPerpendicularToDirection(skip_bottom_levels);
389
390 skip_left_levels = LevelsToSkipAlongDirection(skip_left_levels);
391 skip_right_levels = LevelsToSkipAlongDirection(skip_right_levels);
392 skip_top_levels = LevelsToSkipAlongDirection(skip_top_levels);
393 skip_bottom_levels = LevelsToSkipAlongDirection(skip_bottom_levels);
394
395 int diagonal_distance = std::max(width, height);
396
397 DCHECK(triangular_sequences_.empty());
398 triangular_sequences_.resize(8);
399 // TODO(prashant.n): Implement precedence in coverage directions instead of
400 // default right direction. http://crbug.com/629052.
401 CoverageDirection* positions = GetCoverageDirectionSequence();
402 DCHECK(positions);
403
404 // RIGHT sequence.
405 if (right_levels > 0) {
406 int start = around_bottom - 1;
407 int end = around_top + 1;
408 int skip_levels =
409 std::max(skip_right_levels,
410 std::max(skip_bottom_levels_perp, skip_top_levels_perp));
411 if (right_levels > skip_levels) {
412 EmplaceAt(
413 GetPositionForDirection(positions, CoverageDirection::RIGHT),
414 TriangularSequence(
415 std::string("r.seq"),
416 Interval(Interval::Type::BACKWARD, start, end, consider_bottom,
417 consider_top, reverse_order_),
418 Interval(Interval::Type::FORWARD, around_right, consider_right,
419 consider_left, consider_right, false),
420 true, skip_levels, width, reverse_order_));
421 }
422 }
423
424 // TOP_RIGHT sequence.
425 if (right_levels > 0 && top_levels > 0) {
426 int skip_levels = std::max(skip_right_levels, skip_top_levels);
427 int diagonal_levels = std::min(right_levels, top_levels);
428 if (diagonal_levels > skip_levels) {
429 EmplaceAt(
430 GetPositionForDirection(positions, CoverageDirection::TOP_RIGHT),
431 TriangularSequence(std::string("tr.seq"),
432 Interval(Interval::Type::DIAGONAL_FORWARD,
433 around_right, around_right, consider_left,
434 consider_right, reverse_order_),
435 Interval(Interval::Type::BACKWARD, around_top,
436 around_top - diagonal_levels + 1,
437 consider_bottom, consider_top, false),
438 false, skip_levels, diagonal_distance,
439 reverse_order_));
440 }
441 }
442
443 // TOP sequence.
444 if (top_levels > 0) {
445 int start = around_right - 1;
446 int end = around_left + 1;
447 int skip_levels =
448 std::max(skip_top_levels,
449 std::max(skip_right_levels_perp, skip_left_levels_perp));
450 if (top_levels > skip_levels) {
451 EmplaceAt(GetPositionForDirection(positions, CoverageDirection::TOP),
452 TriangularSequence(
453 std::string("t.seq"),
454 Interval(Interval::Type::BACKWARD, start, end,
455 consider_right, consider_left, reverse_order_),
456 Interval(Interval::Type::BACKWARD, around_top, consider_top,
457 consider_bottom, consider_top, false),
458 false, skip_levels, height, reverse_order_));
459 }
460 }
461
462 // TOP_LEFT sequence.
463 if (top_levels > 0 && left_levels > 0) {
464 int skip_levels = std::max(skip_top_levels, skip_left_levels);
465 int diagonal_levels = std::min(top_levels, left_levels);
466 if (diagonal_levels > skip_levels) {
467 EmplaceAt(GetPositionForDirection(positions, CoverageDirection::TOP_LEFT),
468 TriangularSequence(
469 std::string("tl.seq"),
470 Interval(Interval::Type::DIAGONAL_BACKWARD, around_left,
471 around_left, consider_right, consider_left,
472 reverse_order_),
473 Interval(Interval::Type::BACKWARD, around_top,
474 around_top - diagonal_levels + 1, consider_bottom,
475 consider_top, false),
476 false, skip_levels, diagonal_distance, reverse_order_));
477 }
478 }
479
480 // LEFT sequence.
481 if (left_levels > 0) {
482 int start = around_top + 1;
483 int end = around_bottom - 1;
484 int skip_levels =
485 std::max(skip_left_levels,
486 std::max(skip_top_levels_perp, skip_bottom_levels_perp));
487 if (left_levels > skip_levels) {
488 EmplaceAt(
489 GetPositionForDirection(positions, CoverageDirection::LEFT),
490 TriangularSequence(
491 std::string("l.seq"),
492 Interval(Interval::Type::FORWARD, start, end, consider_top,
493 consider_bottom, reverse_order_),
494 Interval(Interval::Type::BACKWARD, around_left, consider_left,
495 consider_right, consider_left, false),
496 true, skip_levels, width, reverse_order_));
497 }
498 }
499
500 // BOTTOM_LEFT sequence.
501 if (left_levels > 0 && bottom_levels > 0) {
502 int skip_levels = std::max(skip_left_levels, skip_bottom_levels);
503 int diagonal_levels = std::min(left_levels, bottom_levels);
504 if (diagonal_levels > skip_levels) {
505 EmplaceAt(
506 GetPositionForDirection(positions, CoverageDirection::BOTTOM_LEFT),
507 TriangularSequence(std::string("bl.seq"),
508 Interval(Interval::Type::DIAGONAL_BACKWARD,
509 around_left, around_left, consider_right,
510 consider_left, reverse_order_),
511 Interval(Interval::Type::FORWARD, around_bottom,
512 around_bottom + diagonal_levels - 1,
513 consider_top, consider_bottom, false),
514 false, skip_levels, diagonal_distance,
515 reverse_order_));
516 }
517 }
518
519 // BOTTOM sequence.
520 if (bottom_levels > 0) {
521 int start = around_left + 1;
522 int end = around_right - 1;
523 int skip_levels =
524 std::max(skip_bottom_levels,
525 std::max(skip_left_levels_perp, skip_right_levels_perp));
526 if (bottom_levels > skip_levels) {
527 EmplaceAt(
528 GetPositionForDirection(positions, CoverageDirection::BOTTOM),
529 TriangularSequence(
530 std::string("b.seq"),
531 Interval(Interval::Type::FORWARD, start, end, consider_left,
532 consider_right, reverse_order_),
533 Interval(Interval::Type::FORWARD, around_bottom, consider_bottom,
534 consider_top, consider_bottom, false),
535 false, skip_levels, height, reverse_order_));
536 }
537 }
538
539 // BOTTOM_RIGHT sequence.
540 if (bottom_levels > 0 && right_levels > 0) {
541 int skip_levels = std::max(skip_bottom_levels, skip_right_levels);
542 int diagonal_levels = std::min(bottom_levels, right_levels);
543 if (diagonal_levels > skip_levels) {
544 EmplaceAt(
545 GetPositionForDirection(positions, CoverageDirection::BOTTOM_RIGHT),
546 TriangularSequence(std::string("br.seq"),
547 Interval(Interval::Type::DIAGONAL_FORWARD,
548 around_right, around_right, consider_left,
549 consider_right, reverse_order_),
550 Interval(Interval::Type::FORWARD, around_bottom,
551 around_bottom + diagonal_levels - 1,
552 consider_top, consider_bottom, false),
553 false, skip_levels, diagonal_distance,
554 reverse_order_));
555 }
556 }
557
558 current_triangular_sequence_ = GetNextTriangularSequence();
559 if (current_triangular_sequence_) {
560 if (*current_triangular_sequence_)
561 current_traversal_interval_ =
562 current_triangular_sequence_->traversal_interval();
563 UpdateCurrent();
564 }
565 }
566
567 PyramidSequence::operator bool() const {
568 return current_triangular_sequence_ && !triangular_sequences_.empty();
569 }
570
571 PyramidSequence& PyramidSequence::operator++() {
572 Advance();
573 UpdateCurrent();
574
575 return *this;
576 }
577
578 void PyramidSequence::EmplaceAt(int position,
579 TriangularSequence&& triangular_sequence) {
580 TriangularSequence::Iterator it = triangular_sequences_.begin();
581 std::advance(it, position);
582 triangular_sequences_.emplace(it, std::move(triangular_sequence));
583 TriangularSequence::Iterator erase_it = triangular_sequences_.begin();
584 std::advance(erase_it, position + 1);
585 triangular_sequences_.erase(erase_it);
586 }
587
588 void PyramidSequence::Advance() {
589 if (!*this)
590 return;
591
592 ++(*current_traversal_interval_);
593 if (!*current_traversal_interval_) {
594 ++(*current_triangular_sequence_);
595 current_triangular_sequence_ = GetNextTriangularSequence();
596 if (current_triangular_sequence_) {
597 current_traversal_interval_ =
598 current_triangular_sequence_->traversal_interval();
599 }
600 }
601 }
602
603 void PyramidSequence::UpdateCurrent() {
604 while (*this) {
605 if (current_traversal_interval_ && (*current_traversal_interval_)) {
606 if (current_triangular_sequence_->is_swapped()) {
607 index_x_ = current_triangular_sequence_->level_index();
608 index_y_ = current_traversal_interval_->index();
609 } else {
610 index_x_ = current_traversal_interval_->index();
611 index_y_ = current_triangular_sequence_->level_index();
612 }
613
614 if (InConsiderRect() && !InIgnoreRect())
615 break;
616 }
617
618 Advance();
619 }
620 }
621
622 void PyramidSequence::RemoveEmptyTriangularSequences() {
623 triangular_sequences_.erase(
624 std::remove_if(triangular_sequences_.begin(), triangular_sequences_.end(),
625 [](const TriangularSequence& seq) { return !seq; }),
626 triangular_sequences_.end());
627 }
628
629 bool PyramidSequence::InConsiderRect() const {
630 return index_x_ >= consider_left_ && index_x_ <= consider_right_ &&
631 index_y_ >= consider_top_ && index_y_ <= consider_bottom_;
632 }
633
634 bool PyramidSequence::InIgnoreRect() const {
635 return index_x_ >= ignore_left_ && index_x_ <= ignore_right_ &&
636 index_y_ >= ignore_top_ && index_y_ <= ignore_bottom_;
637 }
638
639 // TopDownPyramidSequence implementation.
640 TopDownPyramidSequence::TopDownPyramidSequence() : PyramidSequence(false) {}
641
642 TopDownPyramidSequence::TopDownPyramidSequence(
643 const TopDownPyramidSequence& other) = default;
644
645 TopDownPyramidSequence::TopDownPyramidSequence(TopDownPyramidSequence&& other) =
646 default;
647
648 TopDownPyramidSequence::~TopDownPyramidSequence() {}
649
650 TopDownPyramidSequence& TopDownPyramidSequence::operator=(
651 const TopDownPyramidSequence& other) = default;
652
653 TopDownPyramidSequence& TopDownPyramidSequence::operator=(
654 TopDownPyramidSequence&& other) = default;
655
656 TriangularSequence* TopDownPyramidSequence::GetNextTriangularSequence() {
657 RemoveEmptyTriangularSequences();
658
659 if (triangular_sequences_.empty())
660 return nullptr;
661
662 TriangularSequence::Iterator min_distance_it = triangular_sequences_.begin();
663
664 for (TriangularSequence::Iterator it = triangular_sequences_.begin();
665 it != triangular_sequences_.end(); ++it) {
666 int distance = it->GetMinimumDistance();
667 if (distance == 0)
668 return &(*it);
669
670 if (min_distance_it->GetMinimumDistance() > distance)
671 min_distance_it = it;
672 }
673
674 return &(*min_distance_it);
675 }
676
677 // BottomUpPyramidSequence implementation.
678 BottomUpPyramidSequence::BottomUpPyramidSequence() : PyramidSequence(true) {}
679
680 BottomUpPyramidSequence::BottomUpPyramidSequence(
681 const BottomUpPyramidSequence& other)
682 : PyramidSequence(other) {}
683
684 BottomUpPyramidSequence::BottomUpPyramidSequence(
685 BottomUpPyramidSequence&& other)
686 : PyramidSequence(std::move(other)) {}
687
688 BottomUpPyramidSequence::~BottomUpPyramidSequence() {}
689
690 BottomUpPyramidSequence& BottomUpPyramidSequence::operator=(
691 const BottomUpPyramidSequence& other) {
692 PyramidSequence::operator=(other);
693 return *this;
694 }
695
696 BottomUpPyramidSequence& BottomUpPyramidSequence::operator=(
697 BottomUpPyramidSequence&& other) {
698 PyramidSequence::operator=(std::move(other));
699 return *this;
700 }
701
702 TriangularSequence* BottomUpPyramidSequence::GetNextTriangularSequence() {
703 RemoveEmptyTriangularSequences();
704
705 if (triangular_sequences_.empty())
706 return nullptr;
707
708 TriangularSequence::ReverseIterator max_distance_it =
709 triangular_sequences_.rbegin();
710
711 for (TriangularSequence::ReverseIterator it = triangular_sequences_.rbegin();
712 it != triangular_sequences_.rend(); ++it) {
713 int distance = it->GetMaximumDistance();
714
715 if (max_distance_it->GetMaximumDistance() < distance)
716 max_distance_it = it;
717 }
718
719 return &(*max_distance_it);
720 }
721
722 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698