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

Unified 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: rebase -> used for smoothness tests Created 3 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/base/index_rect.cc ('k') | cc/base/pyramid_sequence.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/base/pyramid_sequence.h
diff --git a/cc/base/pyramid_sequence.h b/cc/base/pyramid_sequence.h
new file mode 100644
index 0000000000000000000000000000000000000000..6524bacc9bc0a5a9c33b49afac3f4e3f1d67766e
--- /dev/null
+++ b/cc/base/pyramid_sequence.h
@@ -0,0 +1,735 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_BASE_PYRAMID_SEQUENCE_H_
+#define CC_BASE_PYRAMID_SEQUENCE_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "cc/base/cc_export.h"
+#include "cc/base/index_rect.h"
+
+namespace cc {
+
+// The pyramid sequence covers following 4 directions while iterating, where R
+// is right, T is top, L is left and B is bottom.
+// T
+// L * R
+// B
+enum class CoverageDirection : int {
+ NONE = -1,
+ RIGHT = 0,
+ TOP,
+ LEFT,
+ BOTTOM,
+ SIZE
+};
+
+namespace internal {
+
+// This class provides iterating mechanism for numbers between defined bounds.
+// e.g. For interval having bounds 3 as start and 6 as end, represented as
+// [3, 6], the interval returns 3, 4, 5, 6 sequence for Iterator traversal and
+// returns 6, 5, 4, 3 for ReverseIterator traversal.
+//
+// start end
+// | |
+// V V
+// ┌───┬───┬───┬───┐
+// │ 3 │ 4 │ 5 │ 6 │
+// └───┴───┴───┴───┘
+class CC_EXPORT Interval {
+ public:
+ class Iterator;
+ class ReverseIterator;
+
+ Interval() : empty_(true) {}
+ Interval(int start, int end) : empty_(false), start_(start), end_(end) {}
+
+ Iterator* Begin();
+ ReverseIterator* ReverseBegin();
+
+ // Return the bounds of the interval.
+ int start() const { return start_; }
+ int end() const { return end_; }
+
+ // Returns true if interval is empty. Empty interval does not return any
+ // index on traversing.
+ bool IsEmpty() const { return empty_; }
+
+ // Returns the distance between |start_| and |end_| which includes both
+ // |start_| and |end_|.
+ int GetSpan() const;
+
+ // Return clamped indices for the given indices.
+ int GetForwardClampedIndex(int index) const;
+ int GetBackwardClampedIndex(int index) const;
+
+ // Clamp this interval to the given interval. For these functions, interval
+ // and other interval to which this interval is to be clammped should be in
+ // the same direction, i.e. both intervals should have either
+ // |start_| <= |end_| or |start_| >= |end_|.
+ void ForwardClampTo(const Interval* other);
+ void BackwardClampTo(const Interval* other);
+
+ // Return the inflated intervals for the given |level|.
+ void ForwardInflate(int level, Interval* output) const;
+ void BackwardInflate(int level, Interval* output) const;
+
+ // Returns true if interval contains the given index.
+ bool Contains(int index) const;
+
+ // For these functions, interval and other interval to which first one is to
+ // be intersected should be in the same direction, i.e. both intervals should
+ // have |start_| <= |end_| or |start_| >= |end_|.
+ bool Intersects(const Interval* interval) const;
+ void Intersect(const Interval* interval);
+
+ // Iterators.
+ class IteratorBase {
+ public:
+ operator bool() const { return within_bounds_; }
+ IteratorBase& operator++();
+ int index() { return current_index_; }
+
+ protected:
+ explicit IteratorBase(Interval* interval);
+
+ virtual bool IsWithinBounds() = 0;
+
+ Interval* interval_;
+ bool within_bounds_;
+ int step_;
+ int current_index_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IteratorBase);
+ };
+
+ class Iterator : public IteratorBase {
+ private:
+ explicit Iterator(Interval* interval);
+
+ bool IsWithinBounds() override;
+
+ friend class Interval;
+
+ DISALLOW_COPY_AND_ASSIGN(Iterator);
+ };
+
+ class ReverseIterator : public IteratorBase {
+ private:
+ explicit ReverseIterator(Interval* interval);
+
+ bool IsWithinBounds() override;
+
+ friend class Interval;
+
+ DISALLOW_COPY_AND_ASSIGN(ReverseIterator);
+ };
+
+ private:
+ bool empty_;
+ int start_;
+ int end_;
+};
+
+// This class provides affinity based interating mechanism for the given
+// |interval| [start, end] with functionality of inflating the |interval|.
+// The interval inflation means expanding the start and end by n steps forward
+// or backward, based on |forward_direction| argument provided. Suppose the
+// LinearSequence has interval [3, 3] i.e. start = 3 and end = 3, the interval
+// inflated by 1 step in forward direction would be [2, 4] and that of in
+// backward direction would be [4, 2].
+// The affinity based traversing means portion of |interval| that intersects
+// with |affinity_interval| is traversed before remaining two portions of
+// |interval|. Internally the |interval| is split up into three sub-intervals
+// before traversing as |affinity_sub_interval_|, |before_sub_interval_| and
+// |after_sub_interval_|. These sub-intervals are traversed instead of directly
+// traversing |interval|. First |affinity_sub_interval_| is traversed fully,
+// then remaining two sub-intervals are traversed in alternative fashion.
+//
+// e.g. Suppose LinearSequence has interval [0, 9] and affinity interval
+// [4, 6], then the interval is splitted into three sub-intervals viz. [4, 6],
+// [3, 0], [7, 9].
+//
+// affinity_sub_interval
+// ┌─────^─────┐
+// ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
+// │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
+// └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
+// └───────v───────┘ └─────v─────┘
+// before_sub_interval after_sub_interval
+//
+// On traversal, Iterator returns the sequence as 4, 5, 6, 3, 7, 2, 8, 1, 9, 0
+// and RerverseIterator returns the sequence as 0, 9, 1, 8, 2, 7, 3, 6, 5, 4.
+class CC_EXPORT LinearSequence {
+ public:
+ class Iterator;
+ class ReverseIterator;
+
+ // The |interval| is used for actual traversal. The |affinity_interval| is
+ // used for defining affinity in the |interval|. While traversing portion of
+ // |interval| which intersects |affinity_interval| is traversed before
+ // remaining portions of the interval. The |inflate_limit| is used to clamp
+ // the |interval|, when it is inflated to any given |level|.
+ LinearSequence(bool forward_direction,
+ std::unique_ptr<Interval> interval,
+ std::unique_ptr<Interval> affinity_interval,
+ std::unique_ptr<Interval> inflate_limit);
+ ~LinearSequence();
+
+ Iterator* Begin();
+ ReverseIterator* ReverseBegin();
+
+ // This function inflates the original |interval| to the given |level|,
+ // where level >= 0.
+ void InflateToLevel(int level);
+
+ // Iterators.
+ class IteratorBase {
+ public:
+ ~IteratorBase();
+
+ operator bool() const { return within_bounds_; }
+ IteratorBase& operator++();
+ int index() { return current_index_; }
+
+ protected:
+ enum class SubIntervalIteratorType : unsigned int {
+ AFFINITY,
+ BEFORE,
+ AFTER
+ };
+
+ explicit IteratorBase(LinearSequence* level_sequence);
+
+ bool IsWithinBounds();
+ virtual SubIntervalIteratorType GetCurrentSubIntervalIteratorType() = 0;
+
+ LinearSequence* level_sequence_;
+ bool within_bounds_;
+ int current_index_;
+ std::unique_ptr<Interval::IteratorBase> sub_interval_iterators_[3];
+ SubIntervalIteratorType current_sub_interval_iterator_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IteratorBase);
+ };
+
+ class Iterator : public IteratorBase {
+ public:
+ ~Iterator();
+
+ private:
+ explicit Iterator(LinearSequence* level_sequence);
+
+ SubIntervalIteratorType GetCurrentSubIntervalIteratorType() override;
+
+ bool before_first_;
+
+ friend class LinearSequence;
+
+ DISALLOW_COPY_AND_ASSIGN(Iterator);
+ };
+
+ class ReverseIterator : public IteratorBase {
+ public:
+ ~ReverseIterator();
+
+ private:
+ explicit ReverseIterator(LinearSequence* level_sequence);
+
+ SubIntervalIteratorType GetCurrentSubIntervalIteratorType() override;
+
+ bool after_first_;
+ int before_sub_interval_span_;
+ int after_sub_interval_span_;
+
+ friend class LinearSequence;
+
+ DISALLOW_COPY_AND_ASSIGN(ReverseIterator);
+ };
+
+ private:
+ void TrisectInterval();
+
+ bool forward_direction_;
+ std::unique_ptr<Interval> interval_;
+ std::unique_ptr<Interval> inflate_limit_;
+ std::unique_ptr<Interval> affinity_interval_;
+
+ std::unique_ptr<Interval> initial_interval_;
+
+ // The |interval_| is split up into following sub-intervals such a way that
+ // they are non-intersecting, adjacent and union of these three sub-intervals
+ // is |interval_|.
+ Interval affinity_sub_interval_;
+ Interval before_sub_interval_;
+ Interval after_sub_interval_;
+
+ DISALLOW_COPY_AND_ASSIGN(LinearSequence);
+};
+
+// This class implements the 2D sequence (x, y) which uses LinearSequence and
+// Interval to represent the co-ordinates. The linear sequence
+// |traversal_sequence| is used for traversing the actual sequence cross the
+// direction and |level_interval| is used for computing the number of levels in
+// the |traversal_sequence|. The interval in |traversal_sequence| can be
+// inflated max to the levels given by |level_interval|.
+// This class uses LevelDistance structure to represent the distance associated
+// with the level. The first level has distance 0, to represent the minimum
+// distance for the origin level, and increments by the step of |distance|
+// given in LevelDistance for every level. Suppose there are 5 levels and
+// distance is 10, then the levels would have distances as 0, 10, 20, 30, 40.
+// The distances are stored in the sorted order in vector, so that the distance
+// at front is minimum, while the distance at back is maximum. The layout of
+// the level distance vector for the example would be (0, 0), (1, 10), (2, 20),
+// (3, 30), (4, 40).
+//
+// e.g. If traversal sequence has interval [3, 4], number of levels is 3 and
+// distance is 10, then the Iterator would give following data on traversal.
+//
+// traversal_sequence level_index
+// [3, 4] 0
+// [2, 5] 1
+// [1, 6] 2
+//
+// The order of iteration for ReverseIterator would be as given below.
+//
+// traversal_sequence level index
+// [1, 6] 2
+// [2, 5] 1
+// [3, 4] 0
+//
+// The indices (x, y) for the iterator are as given below.
+//
+// (3, 0), (4, 0) (level 1)
+// (2, 1), (3, 1), (4, 1), (5, 1), (level 2)
+// (1, 2), (2, 2), (3, 2), (4, 2), (5, 2), (6, 2) (level 3)
+//
+// In a way the original interval in |traversal_sequence| and inflated
+// intervals form triangular geometry in co-ordinate space as given below,
+// hence the name TriangularSequence.
+//
+// x 0 1 2 3 4 5 6
+// y ┌───┬───┬───┬───┬───┬───┬───┐
+// 0 │ │ │ │ 3 │ 4 │ │ │ (level 1, distance 0)
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 1 │ │ │ 2 │ 3 │ 4 │ 5 │ │ (level 2, distance 10)
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 2 │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ (level 3, distance 20)
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 3 │ │ │ │ │ │ │ │
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 4 │ │ │ │ │ │ │ │
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 5 │ │ │ │ │ │ │ │
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 6 │ │ │ │ │ │ │ │
+// └───┴───┴───┴───┴───┴───┴───┘
+class CC_EXPORT TriangularSequence {
+ public:
+ class Iterator;
+ class ReverseIterator;
+
+ // The |traversal_sequence| defines the sequence for traversal and
+ // |level_interval| defines the number of levels for |traversal_sequence|.
+ // If |should_swap_index_representation| is false, then the indices in
+ // |traversal_sequence| represent the x indices and level indices in
+ // |level_interval| represent the y indices, otherwise vice-versa. The
+ // |levels_to_skip| defines the number of levels which should be skipped to
+ // avoid unnecessary traversing. Check PyramidSequence::PyramidSequence() for
+ // more details on level skipping. The |distance| defines the length for the
+ // index.
+ TriangularSequence(CoverageDirection coverage_direction,
+ std::unique_ptr<LinearSequence> traversal_sequence,
+ std::unique_ptr<Interval> level_interval,
+ bool should_swap_index_representation,
+ int levels_to_skip,
+ int distance);
+ ~TriangularSequence();
+
+ Iterator* Begin();
+ ReverseIterator* ReverseBegin();
+
+ CoverageDirection coverage_direction() const { return coverage_direction_; }
+
+ struct LevelDistance {
+ LevelDistance(int interval_level, int level_index, int distance)
+ : interval_level(interval_level),
+ level_index(level_index),
+ distance(distance) {}
+
+ int interval_level;
+ int level_index;
+ int distance;
+ };
+
+ class IteratorBase {
+ public:
+ IteratorBase();
+ ~IteratorBase();
+
+ operator bool() const { return !level_distances_.empty(); }
+ IteratorBase& operator++();
+ LinearSequence* traversal_sequence() {
+ DCHECK(*this);
+ return traversal_sequence_;
+ }
+ int level_index() {
+ DCHECK(*this);
+ return current_level_index_;
+ }
+
+ bool is_index_representation_swapped() const {
+ return should_swap_index_representation_;
+ }
+
+ virtual int GetNextDistance() const = 0;
+
+ protected:
+ explicit IteratorBase(TriangularSequence* triangular_sequence);
+
+ virtual void Advance() = 0;
+ virtual void UpdateCurrent() = 0;
+
+ LinearSequence* traversal_sequence_;
+ bool should_swap_index_representation_;
+ std::vector<LevelDistance> level_distances_;
+ int current_level_index_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IteratorBase);
+ };
+
+ class Iterator : public IteratorBase {
+ public:
+ Iterator();
+
+ // Returns next minimum distance.
+ int GetNextDistance() const override;
+
+ private:
+ explicit Iterator(TriangularSequence* triangular_sequence);
+
+ void Advance() override;
+ void UpdateCurrent() override;
+
+ friend class TriangularSequence;
+
+ DISALLOW_COPY_AND_ASSIGN(Iterator);
+ };
+
+ class ReverseIterator : public IteratorBase {
+ public:
+ ReverseIterator();
+
+ // Returns next maximum distance.
+ int GetNextDistance() const override;
+
+ private:
+ explicit ReverseIterator(TriangularSequence* triangular_sequence);
+
+ void Advance() override;
+ void UpdateCurrent() override;
+
+ friend class TriangularSequence;
+
+ DISALLOW_COPY_AND_ASSIGN(ReverseIterator);
+ };
+
+ typedef std::vector<std::unique_ptr<TriangularSequence>> Vector;
+ typedef std::vector<TriangularSequence::IteratorBase> IteratorVector;
+
+ private:
+ CoverageDirection coverage_direction_;
+ std::unique_ptr<LinearSequence> traversal_sequence_;
+ std::unique_ptr<Interval> level_interval_;
+ bool should_swap_index_representation_;
+ int levels_to_skip_;
+ int distance_;
+
+ DISALLOW_COPY_AND_ASSIGN(TriangularSequence);
+};
+
+// The pyramid sequence consists of 4 triangular sequences, one for each of
+// the directions considered counter-clockwise or clockwise. The ideal pyramid
+// sequence is as given below where it has all triangular sequences in 4
+// directions.
+//
+// ┌───┬───┬───┬───┬───┬───┬───┐
+// │ L │ T │ T │ T │ T │ T │ R │
+// ├───┼───┼───┼───┼───┼───┼───┤
+// │ L │ L │ T │ T │ T │ R │ R │
+// ├───┼───┼───┼───┼───┼───┼───┤
+// │ L │ L │ L │ T │ R │ R │ R │
+// ├───┼───┼───┼───┼───┼───┼───┤
+// │ L │ L │ L │ * │ R │ R │ R │
+// ├───┼───┼───┼───┼───┼───┼───┤
+// │ L │ L │ L │ B │ R │ R │ R │
+// ├───┼───┼───┼───┼───┼───┼───┤
+// │ L │ L │ B │ B │ B │ R │ R │
+// ├───┼───┼───┼───┼───┼───┼───┤
+// │ L │ B │ B │ B │ B │ B │ R │
+// └───┴───┴───┴───┴───┴───┴───┘
+//
+// The triangular sequences for the above pyramid sequence are shown below.
+// * represents the center.
+//
+// (T = top)
+// ┌───┬───┬───┬───┬───┐
+// │ T │ T │ T │ T │ T │
+// ┌───┐ └───┼───┼───┼───┼───┘ ┌───┐
+// │ L │ │ T │ T │ T │ │ R │
+// ├───┼───┐ └───┼───┼───┘ ┌───┼───┤
+// │ L │ L │ │ T │ │ R │ R │
+// ├───┼───┼───┐ └───┘ ┌───┼───┼───┤
+// │ L │ L │ L │ │ R │ R │ R │
+// ├───┼───┼───┤ ┌───┐ ├───┼───┼───┤
+// (L = left) │ L │ L │ L │ │ * │ │ R │ R │ R │ (R = right)
+// ├───┼───┼───┤ └───┘ ├───┼───┼───┤
+// │ L │ L │ L │ │ R │ R │ R │
+// ├───┼───┼───┘ ┌───┐ └───┼───┼───┤
+// │ L │ L │ │ B │ │ R │ R │
+// ├───┼───┘ ┌───┼───┼───┐ └───┼───┤
+// │ L │ │ B │ B │ B │ │ R │
+// └───┘ ┌───┼───┼───┼───┼───┐ └───┘
+// │ B │ B │ B │ B │ B │
+// └───┴───┴───┴───┴───┘
+// (B = bottom)
+//
+// This sequence iterates over all the underlined triangular sequences level by
+// level in increasing or decreasing order of distances. The increasing order of
+// distances can be iterated using Iterator, while the decreasing order of
+// distances can be iterated using ReverseIterator. The default coverage for
+// internal triangular sequences is R, T, L, B forming spiral order.
+// The iteration sequence generated by Iterator is as given below.
+// (Iteration is considered counter-clockwise.)
+//
+// x 0 1 2 3 4 5 6
+// y ┌───┬───┬───┬───┬───┬───┬───┐
+// 0 │ 42│ 36│ 34│ 32│ 33│ 35│ 31│
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 1 │ 40│ 20│ 16│ 14│ 15│ 13│ 29│
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 2 │ 38│ 18│ 6│ 4│ 3│ 11│ 27│
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 3 │ 37│ 17│ 5│ *│ 1│ 9│ 25│
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 4 │ 39│ 19│ 7│ 8│ 2│ 10│ 26│
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 5 │ 41│ 21│ 23│ 22│ 24│ 12│ 28│
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 6 │ 43│ 47│ 45│ 44│ 46│ 48│ 30│
+// └───┴───┴───┴───┴───┴───┴───┘
+//
+// The iteration sequence generated by ReverseIterator is as given below.
+// (Iteration is considered clockwise.)
+//
+// x 0 1 2 3 4 5 6
+// y ┌───┬───┬───┬───┬───┬───┬───┐
+// 0 │ 7│ 13│ 15│ 17│ 16│ 14│ 18│
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 1 │ 9│ 29│ 33│ 35│ 34│ 36│ 20│
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 2 │ 11│ 31│ 43│ 45│ 46│ 38│ 22│
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 3 │ 12│ 32│ 44│ *│ 48│ 40│ 24│
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 4 │ 10│ 30│ 42│ 41│ 47│ 39│ 23│
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 5 │ 8│ 28│ 26│ 27│ 25│ 37│ 21│
+// ├───┼───┼───┼───┼───┼───┼───┤
+// 6 │ 6│ 2│ 4│ 5│ 3│ 1│ 19│
+// └───┴───┴───┴───┴───┴───┴───┘
+class CC_EXPORT PyramidSequence {
+ public:
+ class Iterator;
+ class ReverseIterator;
+
+ // The |around_index_rect| is the index rect computed around some index rect,
+ // called as center index rect. In the above example, center index rect is
+ // (3, 3, 3, 3), so around index rect for it is (2, 4, 2, 4).
+ // The |consider_index_rect| is used to limit the coverage and the
+ // |ignore_index_rect| is used to ignore the indices from coverage. For above
+ // example consider index rect is (0, 6, 0, 6) and ignore index rect is
+ // (-1, -1, -1, -1).
+ // The width and height specify the width and height of the single index. This
+ // is used for traversing indices based on their distances from center index
+ // rect.
+ PyramidSequence(const IndexRect& around_index_rect,
+ const IndexRect& consider_index_rect,
+ const IndexRect& ignore_index_rect,
+ int width,
+ int height);
+ ~PyramidSequence();
+
+ Iterator* Begin();
+ ReverseIterator* ReverseBegin();
+
+ class IteratorBase {
+ public:
+ IteratorBase();
+ ~IteratorBase();
+
+ operator bool() const;
+ IteratorBase& operator++();
+ int index_x() const { return index_x_; }
+ int index_y() const { return index_y_; }
+
+ protected:
+ explicit IteratorBase(const IndexRect& consider_index_rect,
+ const IndexRect& ignore_index_rect);
+
+ virtual bool IsEmpty() const = 0;
+ virtual void Advance() = 0;
+ virtual void UpdateCurrent() = 0;
+
+ IndexRect consider_index_rect_;
+ IndexRect ignore_index_rect_;
+ int index_x_;
+ int index_y_;
+
+ TriangularSequence::IteratorBase* current_triangular_sequence_it_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IteratorBase);
+ };
+
+ class Iterator : public IteratorBase {
+ public:
+ Iterator();
+ ~Iterator();
+
+ private:
+ explicit Iterator(PyramidSequence* pyramid_sequence);
+
+ bool IsEmpty() const override;
+ void Advance() override;
+ void UpdateCurrent() override;
+
+ TriangularSequence::IteratorBase* GetNextTriangularSequenceIterator();
+
+ LinearSequence::Iterator* current_traversal_sequence_iterator_;
+ std::vector<std::unique_ptr<TriangularSequence::Iterator>>
+ triangular_sequence_iterators_;
+
+ friend class PyramidSequence;
+
+ DISALLOW_COPY_AND_ASSIGN(Iterator);
+ };
+
+ class ReverseIterator : public IteratorBase {
+ public:
+ ReverseIterator();
+ ~ReverseIterator();
+
+ private:
+ explicit ReverseIterator(PyramidSequence* pyramid_sequence);
+
+ bool IsEmpty() const override;
+ void Advance() override;
+ void UpdateCurrent() override;
+
+ TriangularSequence::IteratorBase*
+ GetNextTriangularSequenceReverseIterator();
+
+ LinearSequence::ReverseIterator*
+ current_traversal_sequence_reverse_iterator_;
+ std::vector<std::unique_ptr<TriangularSequence::ReverseIterator>>
+ triangular_sequence_reverse_iterators_;
+
+ friend class PyramidSequence;
+
+ DISALLOW_COPY_AND_ASSIGN(ReverseIterator);
+ };
+
+ private:
+ void EmplaceAt(int position,
+ std::unique_ptr<TriangularSequence> triangular_sequence);
+
+ IndexRect consider_index_rect_;
+ IndexRect ignore_index_rect_;
+ TriangularSequence::Vector triangular_sequences_;
+
+ DISALLOW_COPY_AND_ASSIGN(PyramidSequence);
+};
+
+} // namespace internal
+
+class PyramidSequence {
+ public:
+ PyramidSequence();
+ PyramidSequence(const IndexRect& around_index_rect,
+ const IndexRect& consider_index_rect,
+ const IndexRect& ignore_index_rect,
+ int width,
+ int height);
+ PyramidSequence(const PyramidSequence& other);
+ PyramidSequence(PyramidSequence&& other);
+ ~PyramidSequence();
+
+ PyramidSequence& operator=(const PyramidSequence& other);
+ PyramidSequence& operator=(PyramidSequence&& other);
+
+ class Iterator {
+ public:
+ Iterator();
+ Iterator(const Iterator& other);
+ Iterator(Iterator&& other);
+ ~Iterator();
+
+ Iterator& operator=(const Iterator& other);
+ Iterator& operator=(Iterator&& other);
+
+ operator bool() const;
+ Iterator& operator++();
+ int index_x() const;
+ int index_y() const;
+
+ public:
+ explicit Iterator(internal::PyramidSequence::Iterator* ptr);
+
+ std::shared_ptr<internal::PyramidSequence::Iterator> ptr_;
+
+ friend class PyramidSequence;
+ };
+
+ class ReverseIterator {
+ public:
+ ReverseIterator();
+ ReverseIterator(const ReverseIterator& other);
+ ReverseIterator(ReverseIterator&& other);
+ ~ReverseIterator();
+
+ ReverseIterator& operator=(const ReverseIterator& other);
+ ReverseIterator& operator=(ReverseIterator&& other);
+
+ operator bool() const;
+ ReverseIterator& operator++();
+ int index_x() const;
+ int index_y() const;
+
+ private:
+ explicit ReverseIterator(internal::PyramidSequence::ReverseIterator* ptr);
+
+ std::shared_ptr<internal::PyramidSequence::ReverseIterator> ptr_;
+
+ friend class PyramidSequence;
+ };
+
+ Iterator Begin();
+ ReverseIterator ReverseBegin();
+
+ private:
+ std::shared_ptr<internal::PyramidSequence> ptr_;
+};
+
+} // namespace cc
+
+#endif // CC_BASE_PYRAMID_SEQUENCE_H_
« no previous file with comments | « cc/base/index_rect.cc ('k') | cc/base/pyramid_sequence.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698