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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: Source/platform/graphics/paint/DisplayItems.h
diff --git a/Source/platform/graphics/paint/DisplayItems.h b/Source/platform/graphics/paint/DisplayItems.h
index ff125ed3d3d2a9dcbf59e36f76f7e9b05c9726ca..bc4911cbc316647a9a3802e5c4d5245e402716b9 100644
--- a/Source/platform/graphics/paint/DisplayItems.h
+++ b/Source/platform/graphics/paint/DisplayItems.h
@@ -8,9 +8,13 @@
#include "platform/PlatformExport.h"
#include "platform/graphics/paint/DisplayItem.h"
#include "platform/graphics/paint/DrawingDisplayItem.h"
+#include "wtf/Alignment.h"
#include "wtf/Forward.h"
#include "wtf/Noncopyable.h"
#include "wtf/OwnPtr.h"
+#include "wtf/StdLibExtras.h"
+#include "wtf/TypeTraits.h"
+#include "wtf/Utility.h"
#include "wtf/Vector.h"
#include <iterator>
@@ -83,14 +87,14 @@ public:
// Input iterators over the display items.
class Iterator : public std::iterator<std::input_iterator_tag, const ItemHandle> {
public:
- const ItemHandle& operator*() const { m_handle = ItemHandle(m_iterator->get()); return m_handle; }
+ const ItemHandle& operator*() const { m_handle = ItemHandle(*m_iterator); return m_handle; }
const ItemHandle* operator->() const { return &operator*(); }
Iterator& operator++() { ++m_iterator; return *this; }
Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp; }
bool operator==(const Iterator& other) const { return m_iterator == other.m_iterator; }
bool operator!=(const Iterator& other) const { return !(*this == other); }
private:
- using InternalIterator = Vector<OwnPtr<DisplayItem>>::iterator;
+ using InternalIterator = Vector<DisplayItem*>::iterator;
Iterator(const InternalIterator& it) : m_iterator(it) { }
InternalIterator m_iterator;
mutable ItemHandle m_handle;
@@ -100,14 +104,14 @@ public:
class ConstIterator : public std::iterator<std::input_iterator_tag, const ItemHandle> {
public:
ConstIterator(const Iterator& it) : m_iterator(it.m_iterator) { }
- const ItemHandle& operator*() const { m_handle = ItemHandle(m_iterator->get()); return m_handle; }
+ const ItemHandle& operator*() const { m_handle = ItemHandle(*m_iterator); return m_handle; }
const ItemHandle* operator->() const { return &operator*(); }
ConstIterator& operator++() { ++m_iterator; return *this; }
ConstIterator operator++(int) { ConstIterator tmp(*this); operator++(); return tmp; }
bool operator==(const ConstIterator& other) const { return m_iterator == other.m_iterator; }
bool operator!=(const ConstIterator& other) const { return !(*this == other); }
private:
- using InternalIterator = Vector<OwnPtr<DisplayItem>>::const_iterator;
+ using InternalIterator = Vector<DisplayItem*>::const_iterator;
ConstIterator(const InternalIterator& it) : m_iterator(it) { }
InternalIterator m_iterator;
mutable ItemHandle m_handle;
@@ -121,7 +125,7 @@ public:
size_t size() const { return m_items.size(); }
// Random access may not remain O(1) in the future.
- ItemHandle operator[](size_t index) const { return ItemHandle(m_items[index].get()); }
+ ItemHandle operator[](size_t index) const { return ItemHandle(m_items[index]); }
Iterator iteratorAt(size_t index) { return Iterator(m_items.begin() + index); }
ConstIterator iteratorAt(size_t index) const { return ConstIterator(m_items.begin() + index); }
size_t indexForIterator(const Iterator& it) const { return it.m_iterator - m_items.begin(); }
@@ -134,17 +138,31 @@ public:
ConstIterator end() const { return ConstIterator(m_items.end()); }
// Access to the end of the list should also be fast.
- ItemHandle last() const { return ItemHandle(m_items.last().get()); }
-
- // TODO(jbroman): Replace this with something that doesn't first require
- // heap allocation.
- void append(PassOwnPtr<DisplayItem>);
+ ItemHandle last() const { return ItemHandle(m_items.last()); }
// Appends by moving from another list. The item in the list it's being
// removed from will become "gone" in this process, but can still be safely
// destroyed.
void appendByMoving(const Iterator&);
+ // TODO(jbroman): Returning the item here is helpful to initialize a handful
+ // of items, like ClipDisplayItem, but arguably makes this interface leaky.
+ template <typename DisplayItemClass, typename... Args>
+ DisplayItemClass& emplaceBack(Args&&... args)
+ {
+ static_assert(WTF::IsSubclass<DisplayItemClass, DisplayItem>::value,
+ "Can only emplace subclasses of DisplayItem.");
+ static_assert(sizeof(DisplayItemClass) <= maxSize,
+ "DisplayItem subclass is larger than storage buffer.");
+ static_assert(maxAlign % WTF_ALIGN_OF(DisplayItemClass) == 0,
+ "DisplayItem subclass isn't aligned in storage buffer.");
+ DisplayItemClass* displayItem =
+ static_cast<DisplayItemClass*>(appendStorageBuffer().asDisplayItem());
+ new (displayItem) DisplayItemClass(WTF::forward<Args>(args)...);
+ m_items.append(displayItem);
+ return *displayItem;
+ }
+
void removeLast();
void clear();
@@ -156,7 +174,33 @@ public:
void setGone(const Iterator&);
private:
- Vector<OwnPtr<DisplayItem>> m_items;
+ // TODO(jbroman): These need to be kept up to date.
+ // There are compile-time checks to make sure they aren't invalid, at least.
+ // Currently Transform3DDisplayItem is the most constraining.
+ static const size_t maxSize = 64 + sizeof(double) * 16 + sizeof(float) * 4;
+ static const size_t maxAlign = 16;
+
+ // A DisplayItem must be constructed into asDisplayItem() immediately after
+ // construction (at a minimum, before destruction).
+ class StorageBuffer {
+ WTF_MAKE_NONCOPYABLE(StorageBuffer);
+ public:
+ StorageBuffer() { }
+ ~StorageBuffer() { asDisplayItem()->~DisplayItem(); }
+ DisplayItem* asDisplayItem() { return reinterpret_cast_ptr<DisplayItem*>(&m_buffer); }
+ private:
+ WTF::AlignedBuffer<maxSize, maxAlign> m_buffer;
+ };
+
+ using InnerVector = Vector<StorageBuffer>;
+ using OuterVector = Vector<OwnPtr<InnerVector>, 8>;
+
+ StorageBuffer& appendStorageBuffer();
+
+ OuterVector m_buffers;
+
+ // Non-owning pointers into m_buffers.
+ Vector<DisplayItem*> m_items;
};
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698