cc: Use a ListContainer for DisplayItemList to reduce allocations.
[chromium-blink-merge.git] / cc / quads / list_container.h
blob8abc33d62eb6bfa0139f4e7a3c536fb243060f40
1 // Copyright 2014 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.
5 #ifndef CC_QUADS_LIST_CONTAINER_H_
6 #define CC_QUADS_LIST_CONTAINER_H_
8 #include "base/macros.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "cc/base/cc_export.h"
12 namespace cc {
13 class DisplayItem;
14 class DrawQuad;
15 class SharedQuadState;
17 // This class is a container type that handles allocating contiguous memory for
18 // new elements and traversing through elements with either iterator or reverse
19 // iterator. Since this container hands out raw pointers of its elements, it is
20 // very important that this container never reallocate its memory so those raw
21 // pointer will continue to be valid. This class is used to contain
22 // SharedQuadState or DrawQuad. Since the size of each DrawQuad varies, to hold
23 // DrawQuads, the allocations size of each element in this class is
24 // LargestDrawQuadSize while BaseElementType is DrawQuad.
25 template <class BaseElementType>
26 class CC_EXPORT ListContainer {
27 public:
28 // BaseElementType is the type of raw pointers this class hands out; however,
29 // its derived classes might require different memory sizes.
30 // max_size_for_derived_class the largest memory size required for all the
31 // derived classes to use for allocation.
32 explicit ListContainer(size_t max_size_for_derived_class);
33 // This constructor omits input variable for max_size_for_derived_class. This
34 // is used when there is no derived classes from BaseElementType we need to
35 // worry about, and allocation size is just sizeof(BaseElementType).
36 ListContainer();
37 // This constructor reserves the requested memory up front so only single
38 // allocation is needed. When num_of_elements_to_reserve_for is zero, use the
39 // default size.
40 ListContainer(size_t max_size_for_derived_class,
41 size_t num_of_elements_to_reserve_for);
43 ~ListContainer();
45 // This class deals only with char* and void*. It does allocation and passing
46 // out raw pointers, as well as memory deallocation when being destroyed.
47 class CC_EXPORT ListContainerCharAllocator;
49 // This class points to a certain position inside memory of
50 // ListContainerCharAllocator. It is a base class for ListContainer iterators.
51 struct CC_EXPORT PositionInListContainerCharAllocator {
52 ListContainerCharAllocator* ptr_to_container;
53 size_t vector_index;
54 char* item_iterator;
56 PositionInListContainerCharAllocator(
57 const PositionInListContainerCharAllocator& other);
59 PositionInListContainerCharAllocator(ListContainerCharAllocator* container,
60 size_t vector_ind,
61 char* item_iter);
63 bool operator==(const PositionInListContainerCharAllocator& other) const;
64 bool operator!=(const PositionInListContainerCharAllocator& other) const;
66 PositionInListContainerCharAllocator Increment();
67 PositionInListContainerCharAllocator ReverseIncrement();
70 // Iterator classes that can be used to access data.
71 /////////////////////////////////////////////////////////////////
72 class CC_EXPORT Iterator : public PositionInListContainerCharAllocator {
73 // This class is only defined to forward iterate through
74 // ListContainerCharAllocator.
75 public:
76 Iterator(ListContainerCharAllocator* container,
77 size_t vector_ind,
78 char* item_iter,
79 size_t index);
80 ~Iterator();
81 BaseElementType* operator->() const;
82 BaseElementType* operator*() const;
83 Iterator operator++(int unused_post_increment);
84 Iterator& operator++();
86 size_t index() const;
88 private:
89 // This is used to track how many increment has happened since begin(). It
90 // is used to avoid double increment at places an index reference is
91 // needed. For iterator this means begin() corresponds to index 0 and end()
92 // corresponds to index |size|.
93 size_t index_;
96 class CC_EXPORT ConstIterator : public PositionInListContainerCharAllocator {
97 // This class is only defined to forward iterate through
98 // ListContainerCharAllocator.
99 public:
100 ConstIterator(ListContainerCharAllocator* container,
101 size_t vector_ind,
102 char* item_iter,
103 size_t index);
104 ConstIterator(const Iterator& other); // NOLINT
105 ~ConstIterator();
106 const BaseElementType* operator->() const;
107 const BaseElementType* operator*() const;
108 ConstIterator operator++(int unused_post_increment);
109 ConstIterator& operator++();
111 size_t index() const;
113 private:
114 // This is used to track how many increment has happened since begin(). It
115 // is used to avoid double increment at places an index reference is
116 // needed. For iterator this means begin() corresponds to index 0 and end()
117 // corresponds to index |size|.
118 size_t index_;
121 class CC_EXPORT ReverseIterator
122 : public PositionInListContainerCharAllocator {
123 // This class is only defined to reverse iterate through
124 // ListContainerCharAllocator.
125 public:
126 ReverseIterator(ListContainerCharAllocator* container,
127 size_t vector_ind,
128 char* item_iter,
129 size_t index);
130 ~ReverseIterator();
131 BaseElementType* operator->() const;
132 BaseElementType* operator*() const;
133 ReverseIterator operator++(int unused_post_increment);
134 ReverseIterator& operator++();
136 size_t index() const;
138 private:
139 // This is used to track how many increment has happened since rbegin(). It
140 // is used to avoid double increment at places an index reference is
141 // needed. For reverse iterator this means rbegin() corresponds to index 0
142 // and rend() corresponds to index |size|.
143 size_t index_;
146 class CC_EXPORT ConstReverseIterator
147 : public PositionInListContainerCharAllocator {
148 // This class is only defined to reverse iterate through
149 // ListContainerCharAllocator.
150 public:
151 ConstReverseIterator(ListContainerCharAllocator* container,
152 size_t vector_ind,
153 char* item_iter,
154 size_t index);
155 ConstReverseIterator(const ReverseIterator& other); // NOLINT
156 ~ConstReverseIterator();
157 const BaseElementType* operator->() const;
158 const BaseElementType* operator*() const;
159 ConstReverseIterator operator++(int unused_post_increment);
160 ConstReverseIterator& operator++();
162 size_t index() const;
164 private:
165 // This is used to track how many increment has happened since rbegin(). It
166 // is used to avoid double increment at places an index reference is
167 // needed. For reverse iterator this means rbegin() corresponds to index 0
168 // and rend() corresponds to index |size|.
169 size_t index_;
172 // When called, all raw pointers that have been handed out are no longer
173 // valid. Use with caution.
174 // This function does not deallocate memory.
175 void EraseAndInvalidateAllPointers(Iterator position);
177 ConstReverseIterator crbegin() const;
178 ConstReverseIterator crend() const;
179 ConstReverseIterator rbegin() const;
180 ConstReverseIterator rend() const;
181 ReverseIterator rbegin();
182 ReverseIterator rend();
183 ConstIterator cbegin() const;
184 ConstIterator cend() const;
185 ConstIterator begin() const;
186 ConstIterator end() const;
187 Iterator begin();
188 Iterator end();
190 // TODO(weiliangc): front(), back() and ElementAt() function should return
191 // reference, consistent with container-of-object.
192 BaseElementType* front();
193 BaseElementType* back();
194 const BaseElementType* front() const;
195 const BaseElementType* back() const;
197 BaseElementType* ElementAt(size_t index);
198 const BaseElementType* ElementAt(size_t index) const;
200 // Take in derived element type and construct it at location generated by
201 // Allocate().
202 template <typename DerivedElementType>
203 DerivedElementType* AllocateAndConstruct() {
204 return new (Allocate(sizeof(DerivedElementType))) DerivedElementType;
206 // Take in derived element type and copy construct it at location generated by
207 // Allocate().
208 template <typename DerivedElementType>
209 DerivedElementType* AllocateAndCopyFrom(const DerivedElementType* source) {
210 return new (Allocate(sizeof(DerivedElementType)))
211 DerivedElementType(*source);
213 // Construct a new element on top of an existing one.
214 template <typename DerivedElementType>
215 DerivedElementType* ReplaceExistingElement(Iterator at) {
216 at->~BaseElementType();
217 return new (*at) DerivedElementType();
220 size_t size() const;
221 bool empty() const;
222 void clear();
224 size_t AvailableSizeWithoutAnotherAllocationForTesting() const;
226 private:
227 // Hands out memory location for an element at the end of data structure.
228 void* Allocate(size_t size_of_actual_element_in_bytes);
230 scoped_ptr<ListContainerCharAllocator> data_;
232 DISALLOW_COPY_AND_ASSIGN(ListContainer);
235 #if !defined(COMPILER_MSVC)
236 extern template class ListContainer<SharedQuadState>;
237 extern template class ListContainer<DrawQuad>;
238 extern template class ListContainer<DisplayItem>;
239 #endif
240 } // namespace cc
242 #endif // CC_QUADS_LIST_CONTAINER_H_