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

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: 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/base/BUILD.gn ('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..a9c7ba97b98aa37cffa98c6d426cab78237b5828
--- /dev/null
+++ b/cc/base/pyramid_sequence.h
@@ -0,0 +1,353 @@
+// 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 {
+
+// This class provides interating mechanism for the mathematical interval
vmpstr 2016/08/16 00:40:48 iterating
+// [start, end] with functionality for inflating the interval. The interval
+// inflation means expanding the start and end by 1 step. Expanding interval
+// [3, 4] by 1 step would give [2, 5], and by 2 steps would give [1, 6].
+// The iterating mechanism could be used as given below.
+//
+// for (Interval it(FORWARD, 3, 4, 0, 6, false), it; ++it)
vmpstr 2016/08/16 00:40:48 I'm not sure what this example is demonstrating, c
+// int index = it.index();
+//
+// The output for the above example would be 3, 4.
+class CC_EXPORT Interval {
+ public:
+ // The types give below decide how to inflate the interval. Suppose the
+ // interval is [3, 3] i.e. start = 3 and end = 3. The inflated intervals for
+ // different types would be as given below.
+ // FORWARD [2, 4]
vmpstr 2016/08/16 00:40:48 Can we always have just one direction (ie FORWARD)
+ // BACKWARD [4, 2]
+ // DIAGONAL_FORWARD [4, 4]
vmpstr 2016/08/16 00:40:48 Why is [4, 4] a valid interval? It seems to not en
+ // DIAGONAL_BACKWARD [2, 2]
+ enum class Type : uint16_t {
+ FORWARD,
+ BACKWARD,
+ DIAGONAL_FORWARD,
+ DIAGONAL_BACKWARD
vmpstr 2016/08/16 00:40:48 If these are not currently used, please remove the
+ };
+
+ // |reverse_order| decides the direction of iteration order, i.e.
+ // from start to end or from end to start (called as reverse direction).
+ Interval(Type type,
+ int start,
+ int end,
+ int start_inflate_limit,
+ int end_inflate_limit,
+ bool reverse_order);
vmpstr 2016/08/16 00:40:48 As I mentioned in my previous comment, I don't und
+ Interval(const Interval& other);
+ Interval(Interval&& other);
+ ~Interval();
+
+ Interval& operator=(const Interval& other);
+ Interval& operator=(Interval&& other);
+
+ operator bool() const { return within_bounds_; }
+ Interval& operator++();
+
+ int index() { return current_index_; }
+ // This function converts the current interval to level (level >= 0) given.
+ void InflateToLevel(int level);
+ // Returns the distance between |start_| and |end_| which includes both
+ // |start_| and |end_|.
+ int GetSpan();
+
+ private:
+ using InflateToLevelFnPtr = void (Interval::*)(int level);
+ using IsWithinBoundsFnPtr = bool (Interval::*)();
+
+ void Init(Type type);
+ void Reset();
+
+ // Interval inflating functions for different Interval types.
+ void InflateToLevelForward(int levels);
+ void InflateToLevelBackward(int levels);
+ void InflateToLevelDiagonalForward(int levels);
+ void InflateToLevelDiagonalBackward(int levels);
+
+ // Functions for checking the bounds for different Interval types.
+ bool IsWithinBoundsForward();
+ bool IsWithinBoundsBackward();
+ bool IsWithinBoundsDiagonal();
+
+ int start_;
+ int end_;
+ int initial_start_;
+ int initial_end_;
+ int start_inflate_limit_;
+ int end_inflate_limit_;
+ bool reverse_order_;
+ bool within_bounds_;
+ int current_index_;
+ int step_;
+
+ InflateToLevelFnPtr inflate_to_level_ptr_;
+ IsWithinBoundsFnPtr is_within_bounds_ptr_;
+};
vmpstr 2016/08/16 00:40:48 As far as I understand it, this class is just a pa
+
+// This class implements the 2D sequence (x, y) which uses two intervals, one
+// for traversing the actual interval, called as traversal interval and other
+// for computing the number of levels in the traversal interval. The indices of
+// these two intervals represent the x and y indices.
+// LevelDistance means each level has some distance value associated with it.
+// This distance is the distance from the index of the 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 interval is [3, 4], number of levels is 3 and distance is
+// 10, then the triagular sequence would give following data.
+//
+// traversal_interval level index
+// [3, 4] 0
+// [2, 5] 1
+// [1, 6] 2
+//
+// If the |reverse_order| is true, then the iteration sequence would be -
+//
+// traversal_interval level index
+// [1, 6] 2
+// [2, 5] 1
+// [3, 4] 0
+//
+// The indices (x, y) for the normal order 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)
+//
+// The layout as given below looks like a triangle in co-ordinate space and
+// hence the name "TriangularSequence".
+//
+// 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| . . . . . . . .
+class CC_EXPORT TriangularSequence {
+ public:
+ typedef std::list<TriangularSequence> List;
+ typedef List::iterator Iterator;
+ typedef List::reverse_iterator ReverseIterator;
+
+ TriangularSequence();
+ // If |swapped| is false, then the indices in |traversal_interval| represent
+ // the x indice and level indices in |level_interval| represent the y indices,
+ // otherwise vice-versa.
+ TriangularSequence(std::string&& name,
+ Interval&& traversal_interval,
+ Interval&& level_interval,
+ bool swapped,
+ int levels_to_skip,
+ int distance,
+ bool reverse_order);
+ TriangularSequence(const TriangularSequence& other);
+ TriangularSequence(TriangularSequence&& other);
+ ~TriangularSequence();
+
+ TriangularSequence& operator=(const TriangularSequence& other);
+ TriangularSequence& operator=(TriangularSequence&& other);
+
+ operator bool() const { return !level_distances_.empty(); }
+ TriangularSequence& operator++();
+
+ bool is_swapped() { return swapped_; }
+ Interval* traversal_interval() {
+ DCHECK(*this);
+ return &traversal_interval_;
+ }
+ int level_index() {
+ DCHECK(*this);
+ return current_level_index_;
+ }
+ // Get minimum/maximum distance.
+ int GetMinimumDistance() const;
+ int GetMaximumDistance() const;
+
+ private:
+ 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;
+ };
+
+ void Advance();
+ void UpdateCurrent();
+
+ std::string name_;
+ Interval traversal_interval_;
+ bool swapped_;
+ bool reverse_order_;
+ int current_level_index_;
+ std::vector<LevelDistance> level_distances_;
+};
+
+// The pyramid sequence is list of 8 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 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 triangular sequences for the above pyramid sequence are 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 triangular sequences level
+// by level in increasing or decreasing order of distances. The increasing order
+// of distances is called as TopDownPyramidSequence, while the decreasubg order
+// of distances 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_order);
+ 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);
+ operator bool() const;
+ PyramidSequence& operator++();
+
+ int index_x() const { return index_x_; }
+ int index_y() const { return index_y_; }
+
+ protected:
+ void EmplaceAt(int position, TriangularSequence&& triangular_sequence);
+
+ void Advance();
+ void UpdateCurrent();
+
+ void RemoveEmptyTriangularSequences();
+ virtual TriangularSequence* GetNextTriangularSequence() = 0;
+
+ bool InConsiderRect() const;
+ bool InIgnoreRect() const;
+
+ bool reverse_order_;
+ TriangularSequence* current_triangular_sequence_;
+ Interval* current_traversal_interval_;
+ 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_;
+ TriangularSequence::List triangular_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);
+
+ private:
+ TriangularSequence* GetNextTriangularSequence() 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);
+
+ private:
+ TriangularSequence* GetNextTriangularSequence() 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') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698