| 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/ListContainer.h" |
| 9 #include "platform/graphics/paint/DisplayItem.h" | 10 #include "platform/graphics/paint/DisplayItem.h" |
| 10 #include "platform/graphics/paint/DrawingDisplayItem.h" | 11 #include "platform/graphics/paint/DrawingDisplayItem.h" |
| 12 #include "platform/graphics/paint/Transform3DDisplayItem.h" |
| 11 #include "wtf/Forward.h" | 13 #include "wtf/Forward.h" |
| 12 #include "wtf/Noncopyable.h" | 14 #include "wtf/Noncopyable.h" |
| 13 #include "wtf/OwnPtr.h" | 15 #include "wtf/OwnPtr.h" |
| 14 #include "wtf/Vector.h" | 16 #include "wtf/Vector.h" |
| 15 | 17 |
| 16 #include <iterator> | 18 #include <iterator> |
| 17 | 19 |
| 18 class GraphicsContext; | 20 class GraphicsContext; |
| 19 class SkPicture; | 21 class SkPicture; |
| 20 | 22 |
| 21 namespace blink { | 23 namespace blink { |
| 22 | 24 |
| 25 static const size_t kMaximumDisplayItemSize = sizeof(BeginTransform3DDisplayItem
); |
| 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 |
| 24 // opposed to DisplayItemList, which also manages the logic required for caching | 28 // opposed to DisplayItemList, which also manages the logic required for caching |
| 25 // and updating them. | 29 // and updating them. |
| 26 // | 30 // |
| 27 // This is presently implemented on top of a vector of pointers, but the | 31 // This is presently implemented on top of a vector of pointers, but the |
| 28 // implementation is intended to change in the future. | 32 // implementation is intended to change in the future. |
| 29 class PLATFORM_EXPORT DisplayItems { | 33 class PLATFORM_EXPORT DisplayItems { |
| 30 WTF_MAKE_NONCOPYABLE(DisplayItems); | 34 WTF_MAKE_NONCOPYABLE(DisplayItems); |
| 31 public: | 35 public: |
| 32 // Holds a handle to an individual item, and provides restricted access to | 36 // Holds a handle to an individual item, and provides restricted access to |
| (...skipping 43 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, DisplayItems* owningList) : m_itera
tor(it), m_owningList(owningList) { } |
| 95 InternalIterator m_iterator; | 99 InternalIterator m_iterator; |
| 100 DisplayItems* m_owningList; |
| 96 mutable ItemHandle m_handle; | 101 mutable ItemHandle m_handle; |
| 97 friend class DisplayItems; | 102 friend class DisplayItems; |
| 98 friend class ConstIterator; | 103 friend class ConstIterator; |
| 99 }; | 104 }; |
| 100 class ConstIterator : public std::iterator<std::input_iterator_tag, const It
emHandle> { | 105 class ConstIterator : public std::iterator<std::input_iterator_tag, const It
emHandle> { |
| 101 public: | 106 public: |
| 102 ConstIterator(const Iterator& it) : m_iterator(it.m_iterator) { } | 107 ConstIterator(const Iterator& it, const DisplayItems* owningList) : m_it
erator(it.m_iterator), m_owningList(owningList) { } |
| 103 const ItemHandle& operator*() const { m_handle = ItemHandle(m_iterator->
get()); return m_handle; } | 108 const ItemHandle& operator*() const { m_handle = ItemHandle(*m_iterator)
; return m_handle; } |
| 104 const ItemHandle* operator->() const { return &operator*(); } | 109 const ItemHandle* operator->() const { return &operator*(); } |
| 105 ConstIterator& operator++() { ++m_iterator; return *this; } | 110 ConstIterator& operator++() { ++m_iterator; return *this; } |
| 106 ConstIterator operator++(int) { ConstIterator tmp(*this); operator++();
return tmp; } | 111 ConstIterator operator++(int) { ConstIterator tmp(*this); operator++();
return tmp; } |
| 107 bool operator==(const ConstIterator& other) const { return m_iterator ==
other.m_iterator; } | 112 bool operator==(const ConstIterator& other) const { return m_iterator ==
other.m_iterator; } |
| 108 bool operator!=(const ConstIterator& other) const { return !(*this == ot
her); } | 113 bool operator!=(const ConstIterator& other) const { return !(*this == ot
her); } |
| 109 private: | 114 private: |
| 110 using InternalIterator = Vector<OwnPtr<DisplayItem>>::const_iterator; | 115 using InternalIterator = Vector<DisplayItem*>::const_iterator; |
| 111 ConstIterator(const InternalIterator& it) : m_iterator(it) { } | 116 ConstIterator(const InternalIterator& it, const DisplayItems* owningList
) : m_iterator(it), m_owningList(owningList) { } |
| 112 InternalIterator m_iterator; | 117 InternalIterator m_iterator; |
| 118 const DisplayItems* m_owningList; |
| 113 mutable ItemHandle m_handle; | 119 mutable ItemHandle m_handle; |
| 114 friend class DisplayItems; | 120 friend class DisplayItems; |
| 115 }; | 121 }; |
| 116 | 122 |
| 117 DisplayItems(); | 123 DisplayItems(size_t reserveCapacity) |
| 124 : m_ptrs() |
| 125 , m_items(reserveCapacity, kMaximumDisplayItemSize) |
| 126 { |
| 127 m_ptrs.reserveCapacity(reserveCapacity); |
| 128 } |
| 129 |
| 118 ~DisplayItems(); | 130 ~DisplayItems(); |
| 119 | 131 |
| 120 bool isEmpty() const { return m_items.isEmpty(); } | 132 bool isEmpty() const { return m_ptrs.isEmpty(); } |
| 121 size_t size() const { return m_items.size(); } | 133 size_t size() const { return m_ptrs.size(); } |
| 122 | 134 |
| 123 // Random access may not remain O(1) in the future. | 135 // Random access may not remain O(1) in the future. |
| 124 ItemHandle operator[](size_t index) const { return ItemHandle(m_items[index]
.get()); } | 136 ItemHandle operator[](size_t index) const { return ItemHandle(m_ptrs[index])
; } |
| 125 Iterator iteratorAt(size_t index) { return Iterator(m_items.begin() + index)
; } | 137 Iterator iteratorAt(size_t index) { return Iterator(m_ptrs.begin() + index,
this); } |
| 126 ConstIterator iteratorAt(size_t index) const { return ConstIterator(m_items.
begin() + index); } | 138 ConstIterator iteratorAt(size_t index) const { return ConstIterator(m_ptrs.b
egin() + index, this); } |
| 127 size_t indexForIterator(const Iterator& it) const { return it.m_iterator - m
_items.begin(); } | 139 size_t indexForIterator(const Iterator& it) const { return it.m_iterator - m
_ptrs.begin(); } |
| 128 size_t indexForIterator(const ConstIterator& it) const { return it.m_iterato
r - m_items.begin(); } | 140 size_t indexForIterator(const ConstIterator& it) const { return it.m_iterato
r - m_ptrs.begin(); } |
| 129 | 141 |
| 130 // Input iteration, however, should remain cheap. | 142 // Input iteration, however, should remain cheap. |
| 131 Iterator begin() { return Iterator(m_items.begin()); } | 143 Iterator begin() { return Iterator(m_ptrs.begin(), this); } |
| 132 Iterator end() { return Iterator(m_items.end()); } | 144 Iterator end() { return Iterator(m_ptrs.end(), this); } |
| 133 ConstIterator begin() const { return ConstIterator(m_items.begin()); } | 145 ConstIterator begin() const { return ConstIterator(m_ptrs.begin(), this); } |
| 134 ConstIterator end() const { return ConstIterator(m_items.end()); } | 146 ConstIterator end() const { return ConstIterator(m_ptrs.end(), this); } |
| 135 | 147 |
| 136 // Access to the end of the list should also be fast. | 148 // Access to the end of the list should also be fast. |
| 137 ItemHandle last() const { return ItemHandle(m_items.last().get()); } | 149 ItemHandle last() const { return ItemHandle(m_ptrs.last()); } |
| 138 | 150 |
| 139 // TODO(jbroman): Replace this with something that doesn't first require | 151 template<typename DisplayItemClass> |
| 140 // heap allocation. | 152 DisplayItemClass& createAndAppend() |
| 141 void append(PassOwnPtr<DisplayItem>); | 153 { |
| 154 static_assert(WTF::IsSubclass<DisplayItemClass, DisplayItem>::value, |
| 155 "Can only emplace subclasses of DisplayItem."); |
| 156 static_assert(sizeof(DisplayItemClass) <= kMaximumDisplayItemSize, |
| 157 "DisplayItem subclass is larger than storage buffer."); |
| 158 |
| 159 DisplayItemClass& item = *m_items.allocateAndConstruct<DisplayItemClass>
(); |
| 160 m_ptrs.append(&item); |
| 161 return item; |
| 162 } |
| 142 | 163 |
| 143 // Appends by moving from another list. The item in the list it's being | 164 // 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 | 165 // removed from will become "gone" in this process, but can still be safely |
| 145 // destroyed. | 166 // destroyed. |
| 146 void appendByMoving(const Iterator&); | 167 void appendByMoving(const Iterator&); |
| 147 | 168 |
| 148 void removeLast(); | 169 void removeLast(); |
| 149 void clear(); | 170 void clear(); |
| 150 | 171 |
| 151 // TODO(jbroman): Is swap the right primitive? | 172 // TODO(jbroman): Is swap the right primitive? |
| 152 void swap(DisplayItems&); | 173 void swap(DisplayItems&); |
| 153 | 174 |
| 154 // TODO(jbroman): This abstraction is odd and it would be nice to explain it | 175 // TODO(jbroman): This abstraction is odd and it would be nice to explain it |
| 155 // more clearly. | 176 // more clearly. |
| 156 void setGone(const Iterator&); | 177 void setGone(const Iterator&); |
| 157 | 178 |
| 158 private: | 179 private: |
| 159 Vector<OwnPtr<DisplayItem>> m_items; | 180 // Non-owning list of pointers into m_items to support both fast iteration a
nd |
| 181 // the {set,is}Gone concept. |
| 182 // TODO(pdr): Remove or clairify {set,is}Gone. |
| 183 Vector<DisplayItem*> m_ptrs; |
| 184 ListContainer<DisplayItem> m_items; |
| 160 }; | 185 }; |
| 161 | 186 |
| 162 } // namespace blink | 187 } // namespace blink |
| 163 | 188 |
| 164 #endif // DisplayItems_h | 189 #endif // DisplayItems_h |
| OLD | NEW |