| 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 template <typename DisplayItemClass, typename... Args> |
| 149 DisplayItemClass& emplaceBack(Args&&... args) |
| 150 { |
| 151 static_assert(WTF::IsSubclass<DisplayItemClass, DisplayItem>::value, |
| 152 "Can only emplace subclasses of DisplayItem."); |
| 153 static_assert(sizeof(DisplayItemClass) <= maxSize, |
| 154 "DisplayItem subclass is larger than storage buffer."); |
| 155 static_assert(maxAlign % WTF_ALIGN_OF(DisplayItemClass) == 0, |
| 156 "DisplayItem subclass isn't aligned in storage buffer."); |
| 157 DisplayItemClass* displayItem = |
| 158 static_cast<DisplayItemClass*>(appendStorageBuffer().asDisplayItem()
); |
| 159 new (displayItem) DisplayItemClass(WTF::forward<Args>(args)...); |
| 160 m_items.append(displayItem); |
| 161 return *displayItem; |
| 162 } |
| 163 |
| 148 void removeLast(); | 164 void removeLast(); |
| 149 void clear(); | 165 void clear(); |
| 150 | 166 |
| 151 // TODO(jbroman): Is swap the right primitive? | 167 // TODO(jbroman): Is swap the right primitive? |
| 152 void swap(DisplayItems&); | 168 void swap(DisplayItems&); |
| 153 | 169 |
| 154 // TODO(jbroman): This abstraction is odd and it would be nice to explain it | 170 // TODO(jbroman): This abstraction is odd and it would be nice to explain it |
| 155 // more clearly. | 171 // more clearly. |
| 156 void setGone(const Iterator&); | 172 void setGone(const Iterator&); |
| 157 | 173 |
| 158 private: | 174 private: |
| 159 Vector<OwnPtr<DisplayItem>> m_items; | 175 // TODO(jbroman): These need to be kept up to date. |
| 176 // There are compile-time checks to make sure they aren't invalid, at least. |
| 177 // Currently Transform3DDisplayItem is the most constraining. |
| 178 static const size_t maxSize = 64 + sizeof(double) * 16 + sizeof(float) * 4; |
| 179 static const size_t maxAlign = 16; |
| 180 |
| 181 // A DisplayItem must be constructed into asDisplayItem() immediately after |
| 182 // construction (at a minimum, before destruction). |
| 183 class StorageBuffer { |
| 184 WTF_MAKE_NONCOPYABLE(StorageBuffer); |
| 185 public: |
| 186 StorageBuffer() { } |
| 187 ~StorageBuffer() { asDisplayItem()->~DisplayItem(); } |
| 188 DisplayItem* asDisplayItem() { return reinterpret_cast_ptr<DisplayItem*>
(&m_buffer); } |
| 189 private: |
| 190 WTF::AlignedBuffer<maxSize, maxAlign> m_buffer; |
| 191 }; |
| 192 |
| 193 using InnerVector = Vector<StorageBuffer>; |
| 194 using OuterVector = Vector<OwnPtr<InnerVector>, 8>; |
| 195 |
| 196 StorageBuffer& appendStorageBuffer(); |
| 197 |
| 198 OuterVector m_buffers; |
| 199 |
| 200 // Non-owning pointers into m_buffers. |
| 201 Vector<DisplayItem*> m_items; |
| 160 }; | 202 }; |
| 161 | 203 |
| 162 } // namespace blink | 204 } // namespace blink |
| 163 | 205 |
| 164 #endif // DisplayItems_h | 206 #endif // DisplayItems_h |
| OLD | NEW |