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

Side by Side Diff: Source/platform/graphics/paint/DisplayItems.h

Issue 1192443003: [Slimming Paint] Blink-side contiguous allocation of display items. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: need a constructor with WTF_MAKE_NONCOPYABLE Created 5 years, 6 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 | Annotate | Revision Log
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698