1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
// Copyright 2012 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 CCLayerIterator_h
#define CCLayerIterator_h
#include "CCLayerTreeHostCommon.h"
#include <wtf/PassOwnPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
// These classes provide means to iterate over the RenderSurface-Layer tree.
// Example code follows, for a tree of LayerChromium/RenderSurfaceChromium objects. See below for details.
//
// void doStuffOnLayers(const Vector<RefPtr<LayerChromium> >& renderSurfaceLayerList)
// {
// typedef CCLayerIterator<LayerChromium, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType;
//
// CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
// for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
// // Only one of these will be true
// if (it.representsTargetRenderSurface())
// foo(*it); // *it is a layer representing a target RenderSurface
// if (it.representsContributingRenderSurface())
// bar(*it); // *it is a layer representing a RenderSurface that contributes to the layer's target RenderSurface
// if (it.representsItself())
// baz(*it); // *it is a layer representing itself, as it contributes to its own target RenderSurface
// }
// }
// A RenderSurface R may be referred to in one of two different contexts. One RenderSurface is "current" at any time, for
// whatever operation is being performed. This current surface is referred to as a target surface. For example, when R is
// being painted it would be the target surface. Once R has been painted, its contents may be included into another
// surface S. While S is considered the target surface when it is being painted, R is called a contributing surface
// in this context as it contributes to the content of the target surface S.
//
// The iterator's current position in the tree always points to some layer. The state of the iterator indicates the role of the
// layer, and will be one of the following three states. A single layer L will appear in the iteration process in at least one,
// and possibly all, of these states.
// 1. Representing the target surface: The iterator in this state, pointing at layer L, indicates that the target RenderSurface
// is now the surface owned by L. This will occur exactly once for each RenderSurface in the tree.
// 2. Representing a contributing surface: The iterator in this state, pointing at layer L, refers to the RenderSurface owned
// by L as a contributing surface, without changing the current target RenderSurface.
// 3. Representing itself: The iterator in this state, pointing at layer L, refers to the layer itself, as a child of the
// current target RenderSurface.
//
// The BackToFront iterator will return a layer representing the target surface before returning layers representing themselves
// as children of the current target surface. Whereas the FrontToBack ordering will iterate over children layers of a surface
// before the layer representing the surface as a target surface.
//
// To use the iterators:
//
// Create a stepping iterator and end iterator by calling CCLayerIterator::begin() and CCLayerIterator::end() and passing in the
// list of layers owning target RenderSurfaces. Step through the tree by incrementing the stepping iterator while it is != to
// the end iterator. At each step the iterator knows what the layer is representing, and you can query the iterator to decide
// what actions to perform with the layer given what it represents.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Non-templated constants
struct CCLayerIteratorValue {
static const int InvalidTargetRenderSurfaceLayerIndex = -1;
// This must be -1 since the iterator action code assumes that this value can be
// reached by subtracting one from the position of the first layer in the current
// target surface's child layer list, which is 0.
static const int LayerIndexRepresentingTargetRenderSurface = -1;
};
// The position of a layer iterator that is independent of its many template types.
template <typename LayerType>
struct CCLayerIteratorPosition {
bool representsTargetRenderSurface;
bool representsContributingRenderSurface;
bool representsItself;
LayerType* targetRenderSurfaceLayer;
LayerType* currentLayer;
};
// An iterator class for walking over layers in the RenderSurface-Layer tree.
template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename IteratorActionType>
class CCLayerIterator {
typedef CCLayerIterator<LayerType, LayerList, RenderSurfaceType, IteratorActionType> CCLayerIteratorType;
public:
CCLayerIterator() : m_renderSurfaceLayerList(0) { }
static CCLayerIteratorType begin(const LayerList* renderSurfaceLayerList) { return CCLayerIteratorType(renderSurfaceLayerList, true); }
static CCLayerIteratorType end(const LayerList* renderSurfaceLayerList) { return CCLayerIteratorType(renderSurfaceLayerList, false); }
CCLayerIteratorType& operator++() { m_actions.next(*this); return *this; }
bool operator==(const CCLayerIterator& other) const
{
return m_targetRenderSurfaceLayerIndex == other.m_targetRenderSurfaceLayerIndex
&& m_currentLayerIndex == other.m_currentLayerIndex;
}
bool operator!=(const CCLayerIteratorType& other) const { return !(*this == other); }
LayerType* operator->() const { return currentLayer(); }
LayerType* operator*() const { return currentLayer(); }
bool representsTargetRenderSurface() const { return currentLayerRepresentsTargetRenderSurface(); }
bool representsContributingRenderSurface() const { return !representsTargetRenderSurface() && currentLayerRepresentsContributingRenderSurface(); }
bool representsItself() const { return !representsTargetRenderSurface() && !representsContributingRenderSurface(); }
LayerType* targetRenderSurfaceLayer() const { return getRawPtr((*m_renderSurfaceLayerList)[m_targetRenderSurfaceLayerIndex]); }
operator const CCLayerIteratorPosition<LayerType>() const
{
CCLayerIteratorPosition<LayerType> position;
position.representsTargetRenderSurface = representsTargetRenderSurface();
position.representsContributingRenderSurface = representsContributingRenderSurface();
position.representsItself = representsItself();
position.targetRenderSurfaceLayer = targetRenderSurfaceLayer();
position.currentLayer = currentLayer();
return position;
}
private:
CCLayerIterator(const LayerList* renderSurfaceLayerList, bool start)
: m_renderSurfaceLayerList(renderSurfaceLayerList)
, m_targetRenderSurfaceLayerIndex(0)
{
for (size_t i = 0; i < renderSurfaceLayerList->size(); ++i) {
if (!(*renderSurfaceLayerList)[i]->renderSurface()) {
ASSERT_NOT_REACHED();
m_actions.end(*this);
return;
}
}
if (start && !renderSurfaceLayerList->isEmpty())
m_actions.begin(*this);
else
m_actions.end(*this);
}
inline static LayerChromium* getRawPtr(const RefPtr<LayerChromium>& ptr) { return ptr.get(); }
inline static CCLayerImpl* getRawPtr(CCLayerImpl* ptr) { return ptr; }
inline LayerType* currentLayer() const { return currentLayerRepresentsTargetRenderSurface() ? targetRenderSurfaceLayer() : getRawPtr(targetRenderSurfaceChildren()[m_currentLayerIndex]); }
inline bool currentLayerRepresentsContributingRenderSurface() const { return CCLayerTreeHostCommon::renderSurfaceContributesToTarget<LayerType>(currentLayer(), targetRenderSurfaceLayer()->id()); }
inline bool currentLayerRepresentsTargetRenderSurface() const { return m_currentLayerIndex == CCLayerIteratorValue::LayerIndexRepresentingTargetRenderSurface; }
inline RenderSurfaceType* targetRenderSurface() const { return targetRenderSurfaceLayer()->renderSurface(); }
inline const LayerList& targetRenderSurfaceChildren() const { return targetRenderSurface()->layerList(); }
IteratorActionType m_actions;
const LayerList* m_renderSurfaceLayerList;
// The iterator's current position.
// A position in the renderSurfaceLayerList. This points to a layer which owns the current target surface.
// This is a value from 0 to n-1 (n = size of renderSurfaceLayerList = number of surfaces). A value outside of
// this range (for example, CCLayerIteratorValue::InvalidTargetRenderSurfaceLayerIndex) is used to
// indicate a position outside the bounds of the tree.
int m_targetRenderSurfaceLayerIndex;
// A position in the list of layers that are children of the current target surface. When pointing to one of
// these layers, this is a value from 0 to n-1 (n = number of children). Since the iterator must also stop at
// the layers representing the target surface, this is done by setting the currentLayerIndex to a value of
// CCLayerIteratorValue::LayerRepresentingTargetRenderSurface.
int m_currentLayerIndex;
friend struct CCLayerIteratorActions;
};
// Orderings for iterating over the RenderSurface-Layer tree.
struct CCLayerIteratorActions {
// Walks layers sorted by z-order from back to front.
class BackToFront {
public:
template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
void begin(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
void end(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
void next(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
private:
int m_highestTargetRenderSurfaceLayer;
};
// Walks layers sorted by z-order from front to back
class FrontToBack {
public:
template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
void begin(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
void end(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
void next(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
private:
template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
void goToHighestInSubtree(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
};
};
} // namespace WebCore
#endif
|