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

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: 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 side-by-side diff with in-line comments
Download patch
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..c98e673294ebb31fa3a07bf21d26551822b3fe33
--- /dev/null
+++ b/cc/base/pyramid_sequence.h
@@ -0,0 +1,389 @@
+// 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 <list>
+#include <vector>
+
+#include "base/logging.h"
+#include "cc/base/cc_export.h"
+
+namespace cc {
+
+// Triangular sequence is the representation of numbers in triangular form. This
+// takes initial |interval| (start <= number <= end), and inflates that interval
+// by the |levels| given, keeping the interval limit defined by the
+// |interval_inflate_limit|.
+//
+// e.g. With intial interval of [3, 4] and levels 4, the triagular sequence
+// would be as given below.
+// 3 4 (level 1)
+// 2 3 4 5 (level 2)
+// 1 2 3 4 5 6 (level 3)
+// 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
+//
+// With inflate limit of interval [2, 5] defined for the above example, the
+// sequence would be as given below.
+// 3 4
+// 2 3 4 5
+// 2 3 4 5
+// 2 3 4 5
+//
+// With inflate limit of interval [3, 10] defined for the above example, the
+// sequence would be as given below.
+// 3 4
+// 3 4 5
+// 3 4 5 6
+// 3 4 5 6 7
+// The triangular sequence can be of four different types as given below.
+// 1. FORWARD - start <= end as depicted in above example.
+// 2. BACKWARD - start >= end, e.g. initial interval [4, 3]
+// 4 3
+// 5 4 3 2
+// 3. DIAGONAL_FORWARD - start == end, in this case inflation happens in
+// positive direction.
+// e.g. 2, 3, 4, 5
+// 4. DIAGONAL_BACKWARD - start == end, in this case inflation happens in
+// negative direction.
+// e.g. 5, 4, 3, 2
+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
+ public:
+ enum class Type : uint16_t {
+ FORWARD,
+ BACKWARD,
+ DIAGONAL_FORWARD,
+ DIAGONAL_BACKWARD
+ };
+
+ // Interval representing start and end, mathematical interval [start, end].
+ struct Interval {
+ Interval(int start, int end) : start(start), end(end) {}
+ 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
+ Interval(Interval&& other) = default;
+ Interval& operator=(const Interval& other) = default;
+ Interval& operator=(Interval&& other) = default;
+
+ int start;
+ int end;
+ };
+
+ // |name| - Name for the sequence.
+ // |type| - Type of the sequence.
+ // |interval| - Initial interval.
+ // |interval_inflate_limit| - Inflating limit for interval.
+ // |levels| - Number of times inflation should happen.
+ // |levels_to_skip| - Number of levels to skip. The inital interval is
+ // inflated to this value, so that the interval to start the sequence is
+ // pointed to the required level.
+ // |reverse| - If true the initial interval is inflated to the last level and
+ // sequence is continued from |levels| to |levels_to_skip|.
+ TriangularSequence(std::string&& name,
+ Type type,
+ Interval&& interval,
+ Interval&& interval_inflate_limit,
+ int levels,
+ int levels_to_skip,
+ bool reverse);
+ TriangularSequence(const TriangularSequence& other);
+ TriangularSequence(TriangularSequence&& other);
+ ~TriangularSequence();
+
+ TriangularSequence& operator=(const TriangularSequence& other);
+ TriangularSequence& operator=(TriangularSequence&& other);
+
+ // Returns whether the sequence at the current level is overflowing the limits
+ // of the current interval.
+ bool is_within_bounds() { return within_bounds_; }
+
+ int GetInitialIntervalSpan();
+
+ // Get the current sequence number, if the number has overflown the current
+ // level's interval, then interval is inflated and number starting at the next
+ // interval is returned. If all levels have been traversed, then it returns
+ // last number in the sequence.
+ int GetCurrentSequenceNumber();
+ // 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
+ int GetReverseCurrentSequenceNumber();
+
+ // Advances the sequence number to the next in the current interval. If number
+ // overflows the interval, then |within_bounds_| is set to false.
+ void Advance();
+
+ private:
+ using InflateFn = void (TriangularSequence::*)(int levels);
+ using IsWithinBoundsFn = bool (TriangularSequence::*)();
+
+ void Init(Type type);
+ void Reset();
+
+ // Interval inflating functions for different TriangularSequence types.
+ void InflateForward(int levels);
+ void InflateBackward(int levels);
+ void InflateDiagonalForward(int levels);
+ void InflateDiagonalBackward(int levels);
+
+ // Functions for checking the bounds for different TriangularSequence types.
+ bool IsWithinBoundsForward();
+ bool IsWithinBoundsBackward();
+ bool IsWithinBoundsDiagonal();
+
+ std::string name_;
+ Type type_;
+ Interval interval_;
+ Interval interval_inflate_limit_;
+ Interval initial_interval_;
+ int levels_;
+ int levels_traversed_;
+ int levels_limit_;
+ bool reverse_;
+ bool within_bounds_;
+ int current_sequence_number_;
+ int step_;
+
+ InflateFn inflate_;
+ IsWithinBoundsFn is_within_bounds_;
+};
+
+// This class implements the 2D sequence which uses two triangular sequences,
+// one for traversing the actual sequence and other for computing the number of
+// levels for the traversal sequence.
+//
+// LevelDistance means each level has some length value associated with it. The
+// distance is distance from the viewport or rect of interest. If there are 5
+// levels and distance is 10, then the levels would have distances as given
+// below. 0, 10, 20, 30, 40. The first level starts with 0, so as to represent
+// the minimum distance for that level. The distances are stored in sorted
+// order in the vector, so that distance at front is minimum and 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 is [3, 4], number of levels is 3 and distance is
+// 10, then layout of the level distance sequence would be as given below.
+//
+// x 0 1 2 3 4 5 6 7
+// 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| . . . . . . . .
+//
+// When the above sequence is iterated then the indices output would be 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)
+// At each level change, this sequence conveys that level has changed.
+class CC_EXPORT LevelDistanceSequence {
+ public:
+ typedef std::list<LevelDistanceSequence> List;
+ typedef List::iterator Iterator;
+ typedef List::reverse_iterator ReverseIterator;
+
+ LevelDistanceSequence();
+ // If |reverse| is true, then |traversal_sequence| is iterated from the
+ // interval at farthest level to the initial interval. If |swapped| is false
+ // then the sequence numbers in |traversal_sequence| represent the x index and
+ // sequence numbers in |level_sequence| represent the y index, otherwise vice
+ // versa.
+ LevelDistanceSequence(TriangularSequence&& traversal_sequence,
+ TriangularSequence&& level_sequence,
+ bool swapped,
+ int levels_to_skip,
+ int levels_delta,
+ int distance,
+ bool reverse);
+ LevelDistanceSequence(const LevelDistanceSequence& other);
+ LevelDistanceSequence(LevelDistanceSequence&& other);
+ ~LevelDistanceSequence();
+
+ LevelDistanceSequence& operator=(const LevelDistanceSequence& other);
+ LevelDistanceSequence& operator=(LevelDistanceSequence&& other);
+
+ // Return true if this sequence is valid or not.
+ bool IsValid() const { return !level_distances_.empty(); }
+
+ // Gets current indices.
+ int GetCurrentIndexX() const;
+ int GetCurrentIndexY() const;
+
+ // Get minimum/maximum distance.
+ int GetMinimumDistance() const;
+ int GetMaximumDistance() const;
+
+ // Advances or reverse-advances the |traversal_sequence|. When the interval is
+ // traversed fully, then this function return false for indicating the current
+ // level in |traversal_sequence| has been finished.
+ bool Advance();
+ bool ReverseAdvance();
+
+ private:
+ struct LevelDistance {
+ LevelDistance(int level, int distance) : level(level), distance(distance) {}
+
+ int level;
+ int distance;
+ };
+
+ void Reset();
+
+ TriangularSequence traversal_sequence_;
+ bool swapped_;
+ bool reverse_;
+ int current_sequence_index_;
+ int current_level_index_;
+ std::vector<LevelDistance> level_distances_;
+};
+
+// The pyramid sequence is list of 8 level distance sequences, one for each of
+// the directions considered counter-clockwise or clockwise. The actual order
+// of level distance sequences is computed by the direction in which coverage is
+// required. (See GetCoverageDirectionSequenceForDirections() for more details.)
+// The ideal pyramid sequence is as given below where it has all 8 directions.
+//
+// 2 T T T T T 1
+// L 2 T T T 1 R
+// L L 2 T 1 R R
+// L L L * R R R
+// L L 3 B 4 R R
+// L 3 B B B 4 R
+// 3 B B B B B 4
+//
+// The different level distance sequences for the above pyramid sequence is
+// shown below.
+//
+// (T = top)
+// |
+// (2 = top-left) T T T T T (1 = top-right)
+// 2 T T T 1
+// L 2 T 1 R
+// L L 2 1 R R
+// (L = left) --> L L L * R R R <-- (R = right)
+// L L 3 4 R R
+// L 3 B 4 R
+// 3 B B B 4
+// (3 = bottom-left) B B B B B (4 = bottom-right)
+// |
+// (B = bottom)
+//
+// This sequence iterates over all the underlined level distance sequences level
+// by level in increasing or decreasing order of distances. The increasing order
+// of distance is called as TopDownPyramidSequence, while the other is called as
+// BottomUpPyramidSequence. The iteration sequence generated by top down pyramid
+// sequence is as given below. (Iteration is considered counter-clockwise.)
+//
+// x 0 1 2 3 4 5 6
+// y.---------------------
+// 0| 36 35 34 33 32 31 30
+// 1| 37 16 15 14 13 12 29
+// 2| 38 17 4 3 2 11 28
+// 3| 39 18 5 * 1 10 27
+// 4| 40 19 6 7 8 9 26
+// 5| 41 20 21 22 23 24 25
+// 6| 42 43 44 45 46 47 48
+//
+// The iteration sequence generated by bottom up pyramid sequence is as given
+// below. (Iteration is considered clockwise.)
+//
+// x 0 1 2 3 4 5 6
+// y.----------------------
+// 0| 13 14 15 16 17 18 19
+// 1| 12 33 34 35 36 37 20
+// 2| 11 32 45 46 47 38 21
+// 3| 10 31 44 * 48 39 22
+// 4| 9 30 43 42 41 40 23
+// 5| 8 29 28 27 26 25 24
+// 6| 7 6 5 4 3 2 1
+class CC_EXPORT PyramidSequence {
+ public:
+ explicit PyramidSequence(bool reverse);
+ PyramidSequence(const PyramidSequence& other);
+ PyramidSequence(PyramidSequence&& other);
+ virtual ~PyramidSequence();
+
+ PyramidSequence& operator=(const PyramidSequence& other);
+ PyramidSequence& operator=(PyramidSequence&& other);
+
+ virtual void Init(int around_left,
+ int around_right,
+ int around_top,
+ int around_bottom,
+ int consider_left,
+ int consider_right,
+ int consider_top,
+ int consider_bottom,
+ int ignore_left,
+ int ignore_right,
+ int ignore_top,
+ int ignore_bottom,
+ int width,
+ int height);
+ bool IsTraversed();
+
+ virtual void Advance() = 0;
+
+ void UpdateCurrent();
+ int GetCurrentIndexX() const { return index_x_; }
+ int GetCurrentIndexY() const { return index_y_; }
+
+ protected:
+ virtual LevelDistanceSequence* GetNextLevelDistanceSequence() = 0;
+
+ void EmplaceAt(int position, LevelDistanceSequence&& level_distance_sequence);
+ bool InConsiderRect() const;
+ bool InIgnoreRect() const;
+ void RemoveEmptyLevelDistanceSequences();
+
+ bool reverse_;
+ LevelDistanceSequence* current_level_distance_sequence_;
+ int consider_left_;
+ int consider_right_;
+ int consider_top_;
+ int consider_bottom_;
+ int ignore_left_;
+ int ignore_right_;
+ int ignore_top_;
+ int ignore_bottom_;
+ int index_x_;
+ int index_y_;
+ LevelDistanceSequence::List level_distance_sequences_;
+};
+
+class CC_EXPORT TopDownPyramidSequence : public PyramidSequence {
+ public:
+ TopDownPyramidSequence();
+ TopDownPyramidSequence(const TopDownPyramidSequence& other);
+ TopDownPyramidSequence(TopDownPyramidSequence&& other);
+ ~TopDownPyramidSequence() override;
+
+ TopDownPyramidSequence& operator=(const TopDownPyramidSequence& other);
+ TopDownPyramidSequence& operator=(TopDownPyramidSequence&& other);
+
+ void Advance() override;
+
+ private:
+ LevelDistanceSequence* GetNextLevelDistanceSequence() override;
+};
+
+class CC_EXPORT BottomUpPyramidSequence : public PyramidSequence {
+ public:
+ BottomUpPyramidSequence();
+ BottomUpPyramidSequence(const BottomUpPyramidSequence& other);
+ BottomUpPyramidSequence(BottomUpPyramidSequence&& other);
+ ~BottomUpPyramidSequence() override;
+
+ BottomUpPyramidSequence& operator=(const BottomUpPyramidSequence& other);
+ BottomUpPyramidSequence& operator=(BottomUpPyramidSequence&& other);
+
+ void Advance() override;
+
+ private:
+ LevelDistanceSequence* GetNextLevelDistanceSequence() override;
+};
+
+} // namespace cc
+
+#endif // CC_BASE_PYRAMID_SEQUENCE_H_
« 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