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

Side by Side Diff: cc/quads/list_container.cc

Issue 595733002: Revert of Class for allocating a chunk of memory for RenderPass (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mojojojo
Patch Set: Created 6 years, 3 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 unified diff | Download patch
« no previous file with comments | « cc/quads/list_container.h ('k') | cc/quads/list_container_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "cc/quads/list_container.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "cc/base/scoped_ptr_vector.h"
11 #include "cc/quads/draw_quad.h"
12 #include "cc/quads/shared_quad_state.h"
13
14 namespace {
15 const size_t kDefaultNumElementTypesToReserve = 32;
16 } // namespace
17
18 namespace cc {
19
20 // ListContainerCharAllocator
21 ////////////////////////////////////////////////////
22 // This class deals only with char* and void*. It does allocation and passing
23 // out raw pointers, as well as memory deallocation when being destroyed.
24 template <typename BaseElementType>
25 class ListContainer<BaseElementType>::ListContainerCharAllocator {
26 public:
27 // ListContainerCharAllocator::InnerList
28 /////////////////////////////////////////////
29 // This class holds the raw memory chunk, as well as information about its
30 // size and availability.
31 struct InnerList {
32 scoped_ptr<char> data;
33 // The number of elements in total the memory can hold. The difference
34 // between capacity and size is the how many more elements this list can
35 // hold.
36 size_t capacity;
37 // The number of elements have been put into this list.
38 size_t size;
39 // The size of each element is in bytes. This is used to move from between
40 // elements' memory locations.
41 size_t step;
42
43 InnerList() : capacity(0), size(0), step(0) {}
44
45 void Erase(char* position) {
46 // Confident that destructor is called by caller of this function. Since
47 // ListContainerCharAllocator does not handle construction after
48 // allocation, it doesn't handle desctrution before deallocation.
49 DCHECK_LE(position, LastElement());
50 DCHECK_GE(position, Begin());
51 char* start = position + step;
52 std::copy(start, End(), position);
53
54 --size;
55 // Decrease capacity to avoid creating not full not last InnerList.
56 --capacity;
57 }
58
59 bool IsFull() { return capacity == size; }
60 size_t NumElementsAvailable() const { return capacity - size; }
61
62 void* AddElement() {
63 DCHECK_LT(size, capacity);
64 ++size;
65 return LastElement();
66 }
67
68 char* Begin() const { return data.get(); }
69 char* End() const { return data.get() + size * step; }
70 char* LastElement() const { return data.get() + (size - 1) * step; }
71
72 private:
73 DISALLOW_COPY_AND_ASSIGN(InnerList);
74 };
75
76 explicit ListContainerCharAllocator(size_t element_size)
77 : element_size_(element_size),
78 size_(0),
79 list_count_(0),
80 last_list_(NULL) {
81 AllocateNewList(kDefaultNumElementTypesToReserve);
82 }
83
84 ListContainerCharAllocator(size_t element_size, size_t element_count)
85 : element_size_(element_size),
86 size_(0),
87 list_count_(0),
88 last_list_(NULL) {
89 DCHECK_NE(0u, element_count);
90 AllocateNewList(element_count);
91 }
92
93 ~ListContainerCharAllocator() {}
94
95 void* Allocate() {
96 if (last_list_->IsFull())
97 AllocateNewList(last_list_->capacity * 2);
98
99 ++size_;
100 return last_list_->AddElement();
101 }
102
103 size_t element_size() const { return element_size_; }
104 size_t list_count() const { return list_count_; }
105 size_t size() const { return size_; }
106 bool IsEmpty() const { return size() == 0; }
107
108 size_t Capacity() const {
109 size_t capacity_sum = 0;
110 for (typename ScopedPtrVector<InnerList>::const_iterator iter =
111 storage_.begin();
112 iter != storage_.end();
113 ++iter) {
114 capacity_sum += (*iter)->capacity;
115 }
116 return capacity_sum;
117 }
118
119 void Clear() {
120 size_t initial_allocation_size = storage_.front()->capacity;
121 storage_.clear();
122 list_count_ = 0;
123 last_list_ = NULL;
124 size_ = 0;
125 AllocateNewList(initial_allocation_size);
126 }
127
128 void Erase(PositionInListContainerCharAllocator position) {
129 DCHECK_EQ(this, position.ptr_to_container);
130 storage_[position.vector_index]->Erase(position.item_iterator);
131 // TODO(weiliangc): Free the InnerList if it is empty.
132 --size_;
133 }
134
135 InnerList* InnerListById(size_t id) const {
136 DCHECK_LT(id, list_count_);
137 return storage_[id];
138 }
139
140 void AllocateNewList(size_t list_size) {
141 ++list_count_;
142 scoped_ptr<InnerList> new_list(new InnerList);
143 storage_.push_back(new_list.Pass());
144 last_list_ = storage_.back();
145 InnerList* list = last_list_;
146 list->capacity = list_size;
147 list->size = 0;
148 list->step = element_size_;
149 list->data = make_scoped_ptr(new char[list->capacity * list->step]);
150 }
151
152 size_t NumAvailableElementsInLastList() const {
153 return last_list_->NumElementsAvailable();
154 }
155
156 private:
157 ScopedPtrVector<InnerList> storage_;
158 const size_t element_size_;
159 size_t size_;
160 size_t list_count_;
161 InnerList* last_list_;
162
163 DISALLOW_COPY_AND_ASSIGN(ListContainerCharAllocator);
164 };
165
166 // PositionInListContainerCharAllocator
167 //////////////////////////////////////////////////////
168 template <typename BaseElementType>
169 ListContainer<BaseElementType>::PositionInListContainerCharAllocator::
170 PositionInListContainerCharAllocator(const typename ListContainer<
171 BaseElementType>::PositionInListContainerCharAllocator& other)
172 : ptr_to_container(other.ptr_to_container),
173 vector_index(other.vector_index),
174 item_iterator(other.item_iterator) {
175 }
176
177 template <typename BaseElementType>
178 ListContainer<BaseElementType>::PositionInListContainerCharAllocator::
179 PositionInListContainerCharAllocator(
180 typename ListContainer<BaseElementType>::ListContainerCharAllocator*
181 container,
182 size_t vector_ind,
183 char* item_iter)
184 : ptr_to_container(container),
185 vector_index(vector_ind),
186 item_iterator(item_iter) {
187 }
188
189 template <typename BaseElementType>
190 bool ListContainer<BaseElementType>::PositionInListContainerCharAllocator::
191 operator==(const typename ListContainer<
192 BaseElementType>::PositionInListContainerCharAllocator& other) const {
193 DCHECK_EQ(ptr_to_container, other.ptr_to_container);
194 return vector_index == other.vector_index &&
195 item_iterator == other.item_iterator;
196 }
197
198 template <typename BaseElementType>
199 bool ListContainer<BaseElementType>::PositionInListContainerCharAllocator::
200 operator!=(const typename ListContainer<
201 BaseElementType>::PositionInListContainerCharAllocator& other) const {
202 return !(*this == other);
203 }
204
205 template <typename BaseElementType>
206 typename ListContainer<BaseElementType>::PositionInListContainerCharAllocator
207 ListContainer<
208 BaseElementType>::PositionInListContainerCharAllocator::Increment() {
209 typename ListContainerCharAllocator::InnerList* list =
210 ptr_to_container->InnerListById(vector_index);
211 if (item_iterator == list->LastElement()) {
212 if (vector_index < ptr_to_container->list_count() - 1) {
213 ++vector_index;
214 item_iterator = ptr_to_container->InnerListById(vector_index)->Begin();
215 } else {
216 item_iterator = NULL;
217 }
218 } else {
219 item_iterator += list->step;
220 }
221 return *this;
222 }
223
224 template <typename BaseElementType>
225 typename ListContainer<BaseElementType>::PositionInListContainerCharAllocator
226 ListContainer<
227 BaseElementType>::PositionInListContainerCharAllocator::ReverseIncrement() {
228 typename ListContainerCharAllocator::InnerList* list =
229 ptr_to_container->InnerListById(vector_index);
230 if (item_iterator == list->Begin()) {
231 if (vector_index > 0) {
232 --vector_index;
233 item_iterator =
234 ptr_to_container->InnerListById(vector_index)->LastElement();
235 } else {
236 item_iterator = NULL;
237 }
238 } else {
239 item_iterator -= list->step;
240 }
241 return *this;
242 }
243
244 // ListContainer
245 ////////////////////////////////////////////
246 template <typename BaseElementType>
247 ListContainer<BaseElementType>::ListContainer(size_t max_size_for_derived_class)
248 : data_(new ListContainerCharAllocator(max_size_for_derived_class)) {
249 }
250
251 template <typename BaseElementType>
252 ListContainer<BaseElementType>::ListContainer(
253 size_t max_size_for_derived_class,
254 size_t num_of_elements_to_reserve_for)
255 : data_(new ListContainerCharAllocator(max_size_for_derived_class,
256 num_of_elements_to_reserve_for)) {
257 }
258
259 template <typename BaseElementType>
260 ListContainer<BaseElementType>::ListContainer()
261 : data_(new ListContainerCharAllocator(sizeof(BaseElementType))) {
262 }
263
264 template <typename BaseElementType>
265 ListContainer<BaseElementType>::~ListContainer() {
266 for (Iterator i = begin(); i != end(); ++i) {
267 i->~BaseElementType();
268 }
269 }
270
271 template <typename BaseElementType>
272 void ListContainer<BaseElementType>::EraseAndInvalidateAllPointers(
273 typename ListContainer<BaseElementType>::Iterator position) {
274 BaseElementType* item = &*position;
275 item->~BaseElementType();
276 data_->Erase(position);
277 }
278
279 template <typename BaseElementType>
280 typename ListContainer<BaseElementType>::ConstReverseIterator
281 ListContainer<BaseElementType>::rbegin() const {
282 if (data_->IsEmpty())
283 return ConstReverseIterator(data_.get(), 0, NULL);
284
285 size_t last_id = data_->list_count() - 1;
286 return ConstReverseIterator(
287 data_.get(), last_id, data_->InnerListById(last_id)->LastElement());
288 }
289
290 template <typename BaseElementType>
291 typename ListContainer<BaseElementType>::ConstReverseIterator
292 ListContainer<BaseElementType>::rend() const {
293 return ConstReverseIterator(data_.get(), 0, NULL);
294 }
295
296 template <typename BaseElementType>
297 typename ListContainer<BaseElementType>::ReverseIterator
298 ListContainer<BaseElementType>::rbegin() {
299 if (data_->IsEmpty())
300 return ReverseIterator(data_.get(), 0, NULL);
301
302 size_t last_id = data_->list_count() - 1;
303 return ReverseIterator(
304 data_.get(), last_id, data_->InnerListById(last_id)->LastElement());
305 }
306
307 template <typename BaseElementType>
308 typename ListContainer<BaseElementType>::ReverseIterator
309 ListContainer<BaseElementType>::rend() {
310 return ReverseIterator(data_.get(), 0, NULL);
311 }
312
313 template <typename BaseElementType>
314 typename ListContainer<BaseElementType>::ConstIterator
315 ListContainer<BaseElementType>::begin() const {
316 if (data_->IsEmpty())
317 return ConstIterator(data_.get(), 0, NULL);
318
319 return ConstIterator(data_.get(), 0, data_->InnerListById(0)->Begin());
320 }
321
322 template <typename BaseElementType>
323 typename ListContainer<BaseElementType>::ConstIterator
324 ListContainer<BaseElementType>::end() const {
325 if (data_->IsEmpty())
326 return ConstIterator(data_.get(), 0, NULL);
327
328 size_t last_id = data_->list_count() - 1;
329 return ConstIterator(data_.get(), last_id, NULL);
330 }
331
332 template <typename BaseElementType>
333 typename ListContainer<BaseElementType>::Iterator
334 ListContainer<BaseElementType>::begin() {
335 if (data_->IsEmpty())
336 return Iterator(data_.get(), 0, NULL);
337
338 return Iterator(data_.get(), 0, data_->InnerListById(0)->Begin());
339 }
340
341 template <typename BaseElementType>
342 typename ListContainer<BaseElementType>::Iterator
343 ListContainer<BaseElementType>::end() {
344 if (data_->IsEmpty())
345 return Iterator(data_.get(), 0, NULL);
346
347 size_t last_id = data_->list_count() - 1;
348 return Iterator(data_.get(), last_id, NULL);
349 }
350
351 template <typename BaseElementType>
352 BaseElementType* ListContainer<BaseElementType>::front() {
353 Iterator iter = begin();
354 return &*iter;
355 }
356
357 template <typename BaseElementType>
358 BaseElementType* ListContainer<BaseElementType>::back() {
359 ReverseIterator iter = rbegin();
360 return &*iter;
361 }
362
363 template <typename BaseElementType>
364 const BaseElementType* ListContainer<BaseElementType>::front() const {
365 ConstIterator iter = begin();
366 return &*iter;
367 }
368
369 template <typename BaseElementType>
370 const BaseElementType* ListContainer<BaseElementType>::back() const {
371 ConstReverseIterator iter = rbegin();
372 return &*iter;
373 }
374
375 template <typename BaseElementType>
376 BaseElementType* ListContainer<BaseElementType>::Allocate(
377 size_t size_of_actual_element_in_bytes) {
378 DCHECK_LE(size_of_actual_element_in_bytes, data_->element_size());
379 void* result = data_->Allocate();
380 return static_cast<BaseElementType*>(result);
381 }
382
383 template <typename BaseElementType>
384 size_t ListContainer<BaseElementType>::size() const {
385 return data_->size();
386 }
387
388 template <typename BaseElementType>
389 bool ListContainer<BaseElementType>::empty() const {
390 return data_->IsEmpty();
391 }
392
393 template <typename BaseElementType>
394 void ListContainer<BaseElementType>::clear() {
395 for (Iterator i = begin(); i != end(); ++i) {
396 i->~BaseElementType();
397 }
398 data_->Clear();
399 }
400
401 template <typename BaseElementType>
402 size_t ListContainer<
403 BaseElementType>::AvailableSizeWithoutAnotherAllocationForTesting() const {
404 return data_->NumAvailableElementsInLastList();
405 }
406
407 // ListContainer::Iterator
408 /////////////////////////////////////////////////
409 template <typename BaseElementType>
410 ListContainer<BaseElementType>::Iterator::Iterator(
411 ListContainerCharAllocator* container,
412 size_t vector_ind,
413 char* item_iter)
414 : PositionInListContainerCharAllocator(container, vector_ind, item_iter) {
415 }
416
417 template <typename BaseElementType>
418 ListContainer<BaseElementType>::Iterator::~Iterator() {
419 }
420
421 template <typename BaseElementType>
422 BaseElementType* ListContainer<BaseElementType>::Iterator::operator->() const {
423 return reinterpret_cast<BaseElementType*>(this->item_iterator);
424 }
425
426 template <typename BaseElementType>
427 BaseElementType& ListContainer<BaseElementType>::Iterator::operator*() const {
428 return *(reinterpret_cast<BaseElementType*>(this->item_iterator));
429 }
430
431 template <typename BaseElementType>
432 typename ListContainer<BaseElementType>::Iterator
433 ListContainer<BaseElementType>::Iterator::
434 operator++(int unused_post_increment) {
435 Iterator tmp = *this;
436 operator++();
437 return tmp;
438 }
439
440 template <typename BaseElementType>
441 typename ListContainer<BaseElementType>::Iterator
442 ListContainer<BaseElementType>::Iterator::
443 operator++() {
444 this->Increment();
445 return *this;
446 }
447
448 // ListContainer::ConstIterator
449 /////////////////////////////////////////////////
450 template <typename BaseElementType>
451 ListContainer<BaseElementType>::ConstIterator::ConstIterator(
452 const typename ListContainer<BaseElementType>::Iterator& other)
453 : PositionInListContainerCharAllocator(other) {
454 }
455
456 template <typename BaseElementType>
457 ListContainer<BaseElementType>::ConstIterator::ConstIterator(
458 ListContainerCharAllocator* container,
459 size_t vector_ind,
460 char* item_iter)
461 : PositionInListContainerCharAllocator(container, vector_ind, item_iter) {
462 }
463
464 template <typename BaseElementType>
465 ListContainer<BaseElementType>::ConstIterator::~ConstIterator() {
466 }
467
468 template <typename BaseElementType>
469 const BaseElementType* ListContainer<BaseElementType>::ConstIterator::
470 operator->() const {
471 return reinterpret_cast<const BaseElementType*>(this->item_iterator);
472 }
473
474 template <typename BaseElementType>
475 const BaseElementType& ListContainer<BaseElementType>::ConstIterator::
476 operator*() const {
477 return *(reinterpret_cast<const BaseElementType*>(this->item_iterator));
478 }
479
480 template <typename BaseElementType>
481 typename ListContainer<BaseElementType>::ConstIterator
482 ListContainer<BaseElementType>::ConstIterator::
483 operator++(int unused_post_increment) {
484 ConstIterator tmp = *this;
485 operator++();
486 return tmp;
487 }
488
489 template <typename BaseElementType>
490 typename ListContainer<BaseElementType>::ConstIterator
491 ListContainer<BaseElementType>::ConstIterator::
492 operator++() {
493 this->Increment();
494 return *this;
495 }
496
497 // ListContainer::ReverseIterator
498 /////////////////////////////////////////////////
499 template <typename BaseElementType>
500 ListContainer<BaseElementType>::ReverseIterator::ReverseIterator(
501 ListContainerCharAllocator* container,
502 size_t vector_ind,
503 char* item_iter)
504 : PositionInListContainerCharAllocator(container, vector_ind, item_iter) {
505 }
506
507 template <typename BaseElementType>
508 ListContainer<BaseElementType>::ReverseIterator::~ReverseIterator() {
509 }
510
511 template <typename BaseElementType>
512 BaseElementType* ListContainer<BaseElementType>::ReverseIterator::operator->()
513 const {
514 return reinterpret_cast<BaseElementType*>(this->item_iterator);
515 }
516
517 template <typename BaseElementType>
518 BaseElementType& ListContainer<BaseElementType>::ReverseIterator::operator*()
519 const {
520 return *(reinterpret_cast<BaseElementType*>(this->item_iterator));
521 }
522
523 template <typename BaseElementType>
524 typename ListContainer<BaseElementType>::ReverseIterator
525 ListContainer<BaseElementType>::ReverseIterator::
526 operator++(int unused_post_increment) {
527 ReverseIterator tmp = *this;
528 operator++();
529 return tmp;
530 }
531
532 template <typename BaseElementType>
533 typename ListContainer<BaseElementType>::ReverseIterator
534 ListContainer<BaseElementType>::ReverseIterator::
535 operator++() {
536 this->ReverseIncrement();
537 return *this;
538 }
539
540 // ListContainer::ConstReverseIterator
541 /////////////////////////////////////////////////
542 template <typename BaseElementType>
543 ListContainer<BaseElementType>::ConstReverseIterator::ConstReverseIterator(
544 const typename ListContainer<BaseElementType>::ReverseIterator& other)
545 : PositionInListContainerCharAllocator(other) {
546 }
547
548 template <typename BaseElementType>
549 ListContainer<BaseElementType>::ConstReverseIterator::ConstReverseIterator(
550 ListContainerCharAllocator* container,
551 size_t vector_ind,
552 char* item_iter)
553 : PositionInListContainerCharAllocator(container, vector_ind, item_iter) {
554 }
555
556 template <typename BaseElementType>
557 ListContainer<BaseElementType>::ConstReverseIterator::~ConstReverseIterator() {
558 }
559
560 template <typename BaseElementType>
561 const BaseElementType* ListContainer<BaseElementType>::ConstReverseIterator::
562 operator->() const {
563 return reinterpret_cast<const BaseElementType*>(this->item_iterator);
564 }
565
566 template <typename BaseElementType>
567 const BaseElementType& ListContainer<BaseElementType>::ConstReverseIterator::
568 operator*() const {
569 return *(reinterpret_cast<const BaseElementType*>(this->item_iterator));
570 }
571
572 template <typename BaseElementType>
573 typename ListContainer<BaseElementType>::ConstReverseIterator
574 ListContainer<BaseElementType>::ConstReverseIterator::
575 operator++(int unused_post_increment) {
576 ConstReverseIterator tmp = *this;
577 operator++();
578 return tmp;
579 }
580
581 template <typename BaseElementType>
582 typename ListContainer<BaseElementType>::ConstReverseIterator
583 ListContainer<BaseElementType>::ConstReverseIterator::
584 operator++() {
585 this->ReverseIncrement();
586 return *this;
587 }
588
589 template class ListContainer<SharedQuadState>;
590 template class ListContainer<DrawQuad>;
591
592 } // namespace cc
OLDNEW
« no previous file with comments | « cc/quads/list_container.h ('k') | cc/quads/list_container_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698