Commit 664e2387 authored by Sasha McIntosh's avatar Sasha McIntosh Committed by Commit Bot

Add insert copy method to ListContainer class.

Create a method for inserting copies of a DerivedElementType into a
ListContainer. In a follow up cl, this method will be used to insert
DrawQuads into a render pass quad list.

Test: cc_unittests
Bug: 1022544
Change-Id: Ideb864ab2f46e32c08989150a426e77a213b23e5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2064468
Commit-Queue: Sasha McIntosh <sashamcintosh@chromium.org>
Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#742948}
parent 3144187e
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <memory> #include <memory>
#include "base/logging.h" #include "base/logging.h"
#include "base/optional.h"
#include "cc/base/list_container_helper.h" #include "cc/base/list_container_helper.h"
namespace cc { namespace cc {
...@@ -127,12 +128,21 @@ class ListContainer { ...@@ -127,12 +128,21 @@ class ListContainer {
// Insert |count| new elements of |DerivedElementType| before |at|. This will // Insert |count| new elements of |DerivedElementType| before |at|. This will
// invalidate all outstanding pointers and iterators. Return a valid iterator // invalidate all outstanding pointers and iterators. Return a valid iterator
// for the beginning of the newly inserted segment. // for the beginning of the newly inserted segment.
// If provided, insert copies of |source|. Otherwise new elements are default
// initialized.
template <typename DerivedElementType> template <typename DerivedElementType>
Iterator InsertBeforeAndInvalidateAllPointers(Iterator at, size_t count) { Iterator InsertBeforeAndInvalidateAllPointers(
Iterator at,
size_t count,
const base::Optional<DerivedElementType> source = base::nullopt) {
helper_.InsertBeforeAndInvalidateAllPointers(&at, count); helper_.InsertBeforeAndInvalidateAllPointers(&at, count);
Iterator result = at; Iterator result = at;
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
new (at.item_iterator) DerivedElementType(); if (source) {
new (at.item_iterator) DerivedElementType(source.value());
} else {
new (at.item_iterator) DerivedElementType();
}
++at; ++at;
} }
return result; return result;
......
...@@ -90,6 +90,8 @@ const int kMagicNumberToUseForSimpleDerivedElementThree = 1618; ...@@ -90,6 +90,8 @@ const int kMagicNumberToUseForSimpleDerivedElementThree = 1618;
class SimpleDerivedElement : public DerivedElement { class SimpleDerivedElement : public DerivedElement {
public: public:
SimpleDerivedElement() = default;
explicit SimpleDerivedElement(int val) { value = val; }
~SimpleDerivedElement() override = default; ~SimpleDerivedElement() override = default;
void set_value(int val) { value = val; } void set_value(int val) { value = val; }
int get_value() { return value; } int get_value() { return value; }
...@@ -714,6 +716,117 @@ TEST(ListContainerTest, DeletionWhileIterating) { ...@@ -714,6 +716,117 @@ TEST(ListContainerTest, DeletionWhileIterating) {
EXPECT_TRUE(list.empty()); EXPECT_TRUE(list.empty());
} }
TEST(ListContainerTest, InsertCopyBeforeBegin) {
ListContainer<DerivedElement> list(kCurrentLargestDerivedElementAlign,
kCurrentLargestDerivedElementSize, 0);
const int size = 4;
for (int i = 0; i < size; ++i) {
SimpleDerivedElement* element =
list.AllocateAndConstruct<SimpleDerivedElement>();
element->set_value(i);
}
EXPECT_EQ(static_cast<size_t>(size), list.size());
const int count = 2;
auto insert_element = SimpleDerivedElement(100);
auto iter = list.InsertBeforeAndInvalidateAllPointers<SimpleDerivedElement>(
list.begin(), count, insert_element);
const int expected_result[] = {100, 100, 0, 1, 2, 3};
int iter_index = 0;
for (iter = list.begin(); iter != list.end(); ++iter) {
EXPECT_EQ(expected_result[iter_index],
static_cast<SimpleDerivedElement*>(*iter)->get_value());
++iter_index;
}
EXPECT_EQ(size + count, iter_index);
}
TEST(ListContainerTest, InsertCopyBeforeEnd) {
ListContainer<DerivedElement> list(kCurrentLargestDerivedElementAlign,
kCurrentLargestDerivedElementSize, 0);
const int size = 4;
for (int i = 0; i < size; ++i) {
SimpleDerivedElement* element =
list.AllocateAndConstruct<SimpleDerivedElement>();
element->set_value(i);
}
EXPECT_EQ(static_cast<size_t>(size), list.size());
const int count = 3;
auto insert_element = SimpleDerivedElement(100);
auto iter = list.InsertBeforeAndInvalidateAllPointers<SimpleDerivedElement>(
list.end(), count, insert_element);
const int expected_result[] = {0, 1, 2, 3, 100, 100, 100};
int iter_index = 0;
for (iter = list.begin(); iter != list.end(); ++iter) {
EXPECT_EQ(expected_result[iter_index],
static_cast<SimpleDerivedElement*>(*iter)->get_value());
++iter_index;
}
EXPECT_EQ(size + count, iter_index);
}
TEST(ListContainerTest, InsertCopyBeforeEmpty) {
ListContainer<DerivedElement> list(kCurrentLargestDerivedElementAlign,
kCurrentLargestDerivedElementSize, 0);
const int count = 3;
auto insert_element = SimpleDerivedElement(100);
auto iter = list.InsertBeforeAndInvalidateAllPointers<SimpleDerivedElement>(
list.end(), count, insert_element);
const int expected_result[] = {100, 100, 100};
int iter_index = 0;
for (iter = list.begin(); iter != list.end(); ++iter) {
EXPECT_EQ(expected_result[iter_index],
static_cast<SimpleDerivedElement*>(*iter)->get_value());
++iter_index;
}
EXPECT_EQ(count, iter_index);
}
TEST(ListContainerTest, InsertCopyBeforeMany) {
ListContainer<DerivedElement> list(kCurrentLargestDerivedElementAlign,
kCurrentLargestDerivedElementSize, 0);
// Create a partial list of 1,...,9.
int initial_list[] = {0, 1, 4, 5, 7, 9};
for (const auto& initial_list_element : initial_list) {
SimpleDerivedElement* element =
list.AllocateAndConstruct<SimpleDerivedElement>();
element->set_value(initial_list_element);
}
EXPECT_EQ(base::size(initial_list), list.size());
// Insert the missing elements.
auto iter = list.begin();
while (iter != list.end()) {
auto iter_next = iter;
++iter_next;
int value = static_cast<SimpleDerivedElement*>(*iter)->get_value();
int value_next =
iter_next != list.end()
? static_cast<SimpleDerivedElement*>(*iter_next)->get_value()
: 10;
int count = value_next - value - 1;
iter = list.InsertBeforeAndInvalidateAllPointers<SimpleDerivedElement>(
iter_next, count, SimpleDerivedElement(100));
for (int i = 0; i < count; i++)
iter++;
}
const int expected_result[] = {0, 1, 100, 100, 4, 5, 100, 7, 100, 9};
int iter_index = 0;
for (iter = list.begin(); iter != list.end(); ++iter) {
EXPECT_EQ(expected_result[iter_index],
static_cast<SimpleDerivedElement*>(*iter)->get_value());
++iter_index;
}
EXPECT_EQ(10, iter_index);
}
TEST(ListContainerTest, InsertBeforeBegin) { TEST(ListContainerTest, InsertBeforeBegin) {
ListContainer<DerivedElement> list(kCurrentLargestDerivedElementAlign, ListContainer<DerivedElement> list(kCurrentLargestDerivedElementAlign,
kCurrentLargestDerivedElementSize, 0); kCurrentLargestDerivedElementSize, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment