OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef DisplayItems_h | 5 #ifndef DisplayItems_h |
6 #define DisplayItems_h | 6 #define DisplayItems_h |
7 | 7 |
8 #include "platform/PlatformExport.h" | 8 #include "platform/PlatformExport.h" |
9 #include "platform/graphics/paint/DisplayItem.h" | 9 #include "platform/graphics/paint/DisplayItem.h" |
10 #include "platform/graphics/paint/DrawingDisplayItem.h" | 10 #include "platform/graphics/paint/DrawingDisplayItem.h" |
| 11 #include "wtf/Alignment.h" |
11 #include "wtf/Forward.h" | 12 #include "wtf/Forward.h" |
12 #include "wtf/Noncopyable.h" | 13 #include "wtf/Noncopyable.h" |
13 #include "wtf/OwnPtr.h" | 14 #include "wtf/OwnPtr.h" |
| 15 #include "wtf/StdLibExtras.h" |
| 16 #include "wtf/TypeTraits.h" |
| 17 #include "wtf/Utility.h" |
14 #include "wtf/Vector.h" | 18 #include "wtf/Vector.h" |
15 | 19 |
16 #include <iterator> | 20 #include <iterator> |
17 | 21 |
18 class GraphicsContext; | 22 class GraphicsContext; |
19 class SkPicture; | 23 class SkPicture; |
20 | 24 |
21 namespace blink { | 25 namespace blink { |
22 | 26 |
23 // Encapsulates logic for dealing with a simple list of display items, as | 27 // Encapsulates logic for dealing with a simple list of display items, as |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 ItemHandle() : m_ptr(nullptr) { } | 80 ItemHandle() : m_ptr(nullptr) { } |
77 explicit ItemHandle(DisplayItem* ptr) : m_ptr(ptr) { } | 81 explicit ItemHandle(DisplayItem* ptr) : m_ptr(ptr) { } |
78 | 82 |
79 DisplayItem* m_ptr; | 83 DisplayItem* m_ptr; |
80 friend class DisplayItems; | 84 friend class DisplayItems; |
81 }; | 85 }; |
82 | 86 |
83 // Input iterators over the display items. | 87 // Input iterators over the display items. |
84 class Iterator : public std::iterator<std::input_iterator_tag, const ItemHan
dle> { | 88 class Iterator : public std::iterator<std::input_iterator_tag, const ItemHan
dle> { |
85 public: | 89 public: |
86 const ItemHandle& operator*() const { m_handle = ItemHandle(m_iterator->
get()); return m_handle; } | 90 const ItemHandle& operator*() const { m_handle = ItemHandle(*m_iterator)
; return m_handle; } |
87 const ItemHandle* operator->() const { return &operator*(); } | 91 const ItemHandle* operator->() const { return &operator*(); } |
88 Iterator& operator++() { ++m_iterator; return *this; } | 92 Iterator& operator++() { ++m_iterator; return *this; } |
89 Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp
; } | 93 Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp
; } |
90 bool operator==(const Iterator& other) const { return m_iterator == othe
r.m_iterator; } | 94 bool operator==(const Iterator& other) const { return m_iterator == othe
r.m_iterator; } |
91 bool operator!=(const Iterator& other) const { return !(*this == other);
} | 95 bool operator!=(const Iterator& other) const { return !(*this == other);
} |
92 private: | 96 private: |
93 using InternalIterator = Vector<OwnPtr<DisplayItem>>::iterator; | 97 using InternalIterator = Vector<DisplayItem*>::iterator; |
94 Iterator(const InternalIterator& it) : m_iterator(it) { } | 98 Iterator(const InternalIterator& it) : m_iterator(it) { } |
95 InternalIterator m_iterator; | 99 InternalIterator m_iterator; |
96 mutable ItemHandle m_handle; | 100 mutable ItemHandle m_handle; |
97 friend class DisplayItems; | 101 friend class DisplayItems; |
98 friend class ConstIterator; | 102 friend class ConstIterator; |
99 }; | 103 }; |
100 class ConstIterator : public std::iterator<std::input_iterator_tag, const It
emHandle> { | 104 class ConstIterator : public std::iterator<std::input_iterator_tag, const It
emHandle> { |
101 public: | 105 public: |
102 ConstIterator(const Iterator& it) : m_iterator(it.m_iterator) { } | 106 ConstIterator(const Iterator& it) : m_iterator(it.m_iterator) { } |
103 const ItemHandle& operator*() const { m_handle = ItemHandle(m_iterator->
get()); return m_handle; } | 107 const ItemHandle& operator*() const { m_handle = ItemHandle(*m_iterator)
; return m_handle; } |
104 const ItemHandle* operator->() const { return &operator*(); } | 108 const ItemHandle* operator->() const { return &operator*(); } |
105 ConstIterator& operator++() { ++m_iterator; return *this; } | 109 ConstIterator& operator++() { ++m_iterator; return *this; } |
106 ConstIterator operator++(int) { ConstIterator tmp(*this); operator++();
return tmp; } | 110 ConstIterator operator++(int) { ConstIterator tmp(*this); operator++();
return tmp; } |
107 bool operator==(const ConstIterator& other) const { return m_iterator ==
other.m_iterator; } | 111 bool operator==(const ConstIterator& other) const { return m_iterator ==
other.m_iterator; } |
108 bool operator!=(const ConstIterator& other) const { return !(*this == ot
her); } | 112 bool operator!=(const ConstIterator& other) const { return !(*this == ot
her); } |
109 private: | 113 private: |
110 using InternalIterator = Vector<OwnPtr<DisplayItem>>::const_iterator; | 114 using InternalIterator = Vector<DisplayItem*>::const_iterator; |
111 ConstIterator(const InternalIterator& it) : m_iterator(it) { } | 115 ConstIterator(const InternalIterator& it) : m_iterator(it) { } |
112 InternalIterator m_iterator; | 116 InternalIterator m_iterator; |
113 mutable ItemHandle m_handle; | 117 mutable ItemHandle m_handle; |
114 friend class DisplayItems; | 118 friend class DisplayItems; |
115 }; | 119 }; |
116 | 120 |
117 DisplayItems(); | 121 DisplayItems(); |
118 ~DisplayItems(); | 122 ~DisplayItems(); |
119 | 123 |
120 bool isEmpty() const { return m_items.isEmpty(); } | 124 bool isEmpty() const { return m_items.isEmpty(); } |
121 size_t size() const { return m_items.size(); } | 125 size_t size() const { return m_items.size(); } |
122 | 126 |
123 // Random access may not remain O(1) in the future. | 127 // Random access may not remain O(1) in the future. |
124 ItemHandle operator[](size_t index) const { return ItemHandle(m_items[index]
.get()); } | 128 ItemHandle operator[](size_t index) const { return ItemHandle(m_items[index]
); } |
125 Iterator iteratorAt(size_t index) { return Iterator(m_items.begin() + index)
; } | 129 Iterator iteratorAt(size_t index) { return Iterator(m_items.begin() + index)
; } |
126 ConstIterator iteratorAt(size_t index) const { return ConstIterator(m_items.
begin() + index); } | 130 ConstIterator iteratorAt(size_t index) const { return ConstIterator(m_items.
begin() + index); } |
127 size_t indexForIterator(const Iterator& it) const { return it.m_iterator - m
_items.begin(); } | 131 size_t indexForIterator(const Iterator& it) const { return it.m_iterator - m
_items.begin(); } |
128 size_t indexForIterator(const ConstIterator& it) const { return it.m_iterato
r - m_items.begin(); } | 132 size_t indexForIterator(const ConstIterator& it) const { return it.m_iterato
r - m_items.begin(); } |
129 | 133 |
130 // Input iteration, however, should remain cheap. | 134 // Input iteration, however, should remain cheap. |
131 Iterator begin() { return Iterator(m_items.begin()); } | 135 Iterator begin() { return Iterator(m_items.begin()); } |
132 Iterator end() { return Iterator(m_items.end()); } | 136 Iterator end() { return Iterator(m_items.end()); } |
133 ConstIterator begin() const { return ConstIterator(m_items.begin()); } | 137 ConstIterator begin() const { return ConstIterator(m_items.begin()); } |
134 ConstIterator end() const { return ConstIterator(m_items.end()); } | 138 ConstIterator end() const { return ConstIterator(m_items.end()); } |
135 | 139 |
136 // Access to the end of the list should also be fast. | 140 // Access to the end of the list should also be fast. |
137 ItemHandle last() const { return ItemHandle(m_items.last().get()); } | 141 ItemHandle last() const { return ItemHandle(m_items.last()); } |
138 | |
139 // TODO(jbroman): Replace this with something that doesn't first require | |
140 // heap allocation. | |
141 void append(PassOwnPtr<DisplayItem>); | |
142 | 142 |
143 // Appends by moving from another list. The item in the list it's being | 143 // Appends by moving from another list. The item in the list it's being |
144 // removed from will become "gone" in this process, but can still be safely | 144 // removed from will become "gone" in this process, but can still be safely |
145 // destroyed. | 145 // destroyed. |
146 void appendByMoving(const Iterator&); | 146 void appendByMoving(const Iterator&); |
147 | 147 |
| 148 // TODO(jbroman): Returning the item here is helpful to initialize a handful |
| 149 // of items, like ClipDisplayItem, but arguably makes this interface leaky. |
| 150 template <typename DisplayItemClass, typename... Args> |
| 151 DisplayItemClass& emplaceBack(Args&&... args) |
| 152 { |
| 153 static_assert(WTF::IsSubclass<DisplayItemClass, DisplayItem>::value, |
| 154 "Can only emplace subclasses of DisplayItem."); |
| 155 static_assert(sizeof(DisplayItemClass) <= maxSize, |
| 156 "DisplayItem subclass is larger than storage buffer."); |
| 157 static_assert(maxAlign % WTF_ALIGN_OF(DisplayItemClass) == 0, |
| 158 "DisplayItem subclass isn't aligned in storage buffer."); |
| 159 DisplayItemClass* displayItem = |
| 160 static_cast<DisplayItemClass*>(appendStorageBuffer().asDisplayItem()
); |
| 161 new (displayItem) DisplayItemClass(WTF::forward<Args>(args)...); |
| 162 m_items.append(displayItem); |
| 163 return *displayItem; |
| 164 } |
| 165 |
148 void removeLast(); | 166 void removeLast(); |
149 void clear(); | 167 void clear(); |
150 | 168 |
151 // TODO(jbroman): Is swap the right primitive? | 169 // TODO(jbroman): Is swap the right primitive? |
152 void swap(DisplayItems&); | 170 void swap(DisplayItems&); |
153 | 171 |
154 // TODO(jbroman): This abstraction is odd and it would be nice to explain it | 172 // TODO(jbroman): This abstraction is odd and it would be nice to explain it |
155 // more clearly. | 173 // more clearly. |
156 void setGone(const Iterator&); | 174 void setGone(const Iterator&); |
157 | 175 |
158 private: | 176 private: |
159 Vector<OwnPtr<DisplayItem>> m_items; | 177 // TODO(jbroman): These need to be kept up to date. |
| 178 // There are compile-time checks to make sure they aren't invalid, at least. |
| 179 // Currently Transform3DDisplayItem is the most constraining. |
| 180 static const size_t maxSize = 64 + sizeof(double) * 16 + sizeof(float) * 4; |
| 181 static const size_t maxAlign = 16; |
| 182 |
| 183 // A DisplayItem must be constructed into asDisplayItem() immediately after |
| 184 // construction (at a minimum, before destruction). |
| 185 class StorageBuffer { |
| 186 WTF_MAKE_NONCOPYABLE(StorageBuffer); |
| 187 public: |
| 188 StorageBuffer() { } |
| 189 ~StorageBuffer() { asDisplayItem()->~DisplayItem(); } |
| 190 DisplayItem* asDisplayItem() { return reinterpret_cast_ptr<DisplayItem*>
(&m_buffer); } |
| 191 private: |
| 192 WTF::AlignedBuffer<maxSize, maxAlign> m_buffer; |
| 193 }; |
| 194 |
| 195 using InnerVector = Vector<StorageBuffer>; |
| 196 using OuterVector = Vector<OwnPtr<InnerVector>, 8>; |
| 197 |
| 198 StorageBuffer& appendStorageBuffer(); |
| 199 |
| 200 OuterVector m_buffers; |
| 201 |
| 202 // Non-owning pointers into m_buffers. |
| 203 Vector<DisplayItem*> m_items; |
160 }; | 204 }; |
161 | 205 |
162 } // namespace blink | 206 } // namespace blink |
163 | 207 |
164 #endif // DisplayItems_h | 208 #endif // DisplayItems_h |
OLD | NEW |