| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef DisplayItemList_h | |
| 6 #define DisplayItemList_h | |
| 7 | |
| 8 #include "platform/PlatformExport.h" | |
| 9 #include "platform/RuntimeEnabledFeatures.h" | |
| 10 #include "platform/geometry/IntRect.h" | |
| 11 #include "platform/geometry/LayoutPoint.h" | |
| 12 #include "platform/graphics/ContiguousContainer.h" | |
| 13 #include "platform/graphics/PaintInvalidationReason.h" | |
| 14 #include "platform/graphics/paint/DisplayItem.h" | |
| 15 #include "platform/graphics/paint/DisplayItems.h" | |
| 16 #include "platform/graphics/paint/PaintArtifact.h" | |
| 17 #include "platform/graphics/paint/PaintChunk.h" | |
| 18 #include "platform/graphics/paint/PaintChunker.h" | |
| 19 #include "platform/graphics/paint/Transform3DDisplayItem.h" | |
| 20 #include "wtf/Alignment.h" | |
| 21 #include "wtf/HashMap.h" | |
| 22 #include "wtf/PassOwnPtr.h" | |
| 23 #include "wtf/Utility.h" | |
| 24 #include "wtf/Vector.h" | |
| 25 | |
| 26 namespace blink { | |
| 27 | |
| 28 class GraphicsLayer; | |
| 29 class GraphicsContext; | |
| 30 | |
| 31 static const size_t kInitialDisplayItemsCapacity = 64; | |
| 32 | |
| 33 // Responsible for processing display items as they are produced, and producing | |
| 34 // a final paint artifact when complete. This class includes logic for caching, | |
| 35 // cache invalidation, and merging. | |
| 36 class PLATFORM_EXPORT DisplayItemList { | |
| 37 WTF_MAKE_NONCOPYABLE(DisplayItemList); | |
| 38 WTF_MAKE_FAST_ALLOCATED(DisplayItemList); | |
| 39 public: | |
| 40 static PassOwnPtr<DisplayItemList> create() | |
| 41 { | |
| 42 return adoptPtr(new DisplayItemList()); | |
| 43 } | |
| 44 | |
| 45 // These methods are called during paint invalidation (or paint if SlimmingP
aintSynchronizedPainting is on). | |
| 46 void invalidate(const DisplayItemClientWrapper&, PaintInvalidationReason, co
nst IntRect& previousPaintInvalidationRect, const IntRect& newPaintInvalidationR
ect); | |
| 47 void invalidateUntracked(DisplayItemClient); | |
| 48 void invalidateAll(); | |
| 49 | |
| 50 // Record when paint offsets change during paint. | |
| 51 void invalidatePaintOffset(const DisplayItemClientWrapper&); | |
| 52 #if ENABLE(ASSERT) | |
| 53 bool paintOffsetWasInvalidated(DisplayItemClient) const; | |
| 54 #endif | |
| 55 | |
| 56 // These methods are called during painting. | |
| 57 | |
| 58 // Provide a new set of paint chunk properties to apply to recorded display | |
| 59 // items, for Slimming Paint v2. | |
| 60 // TODO(pdr): This should be moved to PaintArtifact. | |
| 61 void updateCurrentPaintChunkProperties(const PaintChunkProperties&); | |
| 62 | |
| 63 template <typename DisplayItemClass, typename... Args> | |
| 64 void createAndAppend(Args&&... args) | |
| 65 { | |
| 66 static_assert(WTF::IsSubclass<DisplayItemClass, DisplayItem>::value, | |
| 67 "Can only createAndAppend subclasses of DisplayItem."); | |
| 68 static_assert(sizeof(DisplayItemClass) <= kMaximumDisplayItemSize, | |
| 69 "DisplayItem subclass is larger than kMaximumDisplayItemSize."); | |
| 70 | |
| 71 if (displayItemConstructionIsDisabled()) | |
| 72 return; | |
| 73 DisplayItemClass& displayItem = m_newDisplayItems.allocateAndConstruct<D
isplayItemClass>(WTF::forward<Args>(args)...); | |
| 74 processNewItem(displayItem); | |
| 75 } | |
| 76 | |
| 77 // Creates and appends an ending display item to pair with a preceding | |
| 78 // beginning item iff the display item actually draws content. For no-op | |
| 79 // items, rather than creating an ending item, the begin item will | |
| 80 // instead be removed, thereby maintaining brevity of the list. If display | |
| 81 // item construction is disabled, no list mutations will be performed. | |
| 82 template <typename DisplayItemClass, typename... Args> | |
| 83 void endItem(Args&&... args) | |
| 84 { | |
| 85 if (displayItemConstructionIsDisabled()) | |
| 86 return; | |
| 87 if (lastDisplayItemIsNoopBegin()) | |
| 88 removeLastDisplayItem(); | |
| 89 else | |
| 90 createAndAppend<DisplayItemClass>(WTF::forward<Args>(args)...); | |
| 91 } | |
| 92 | |
| 93 // Scopes must be used to avoid duplicated display item ids when we paint so
me object | |
| 94 // multiple times and generate multiple display items with the same type. | |
| 95 // We don't cache display items added in scopes. | |
| 96 void beginScope(); | |
| 97 void endScope(); | |
| 98 | |
| 99 // True if the last display item is a begin that doesn't draw content. | |
| 100 bool lastDisplayItemIsNoopBegin() const; | |
| 101 void removeLastDisplayItem(); | |
| 102 | |
| 103 void beginSkippingCache() { ++m_skippingCacheCount; } | |
| 104 void endSkippingCache() { ASSERT(m_skippingCacheCount > 0); --m_skippingCach
eCount; } | |
| 105 bool skippingCache() const { return m_skippingCacheCount; } | |
| 106 | |
| 107 // Must be called when a painting is finished. If passed, invalidations are
recorded on the given | |
| 108 // GraphicsLayer. | |
| 109 void commitNewDisplayItems(GraphicsLayer* = 0); | |
| 110 | |
| 111 // Returns the approximate memory usage, excluding memory likely to be | |
| 112 // shared with the embedder after copying to WebDisplayItemList. | |
| 113 // Should only be called right after commitNewDisplayItems. | |
| 114 size_t approximateUnsharedMemoryUsage() const; | |
| 115 | |
| 116 // Get the artifact generated after the last commit. | |
| 117 const PaintArtifact& paintArtifact() const; | |
| 118 const DisplayItems& displayItems() const { return paintArtifact().displayIte
ms(); } | |
| 119 const Vector<PaintChunk>& paintChunks() const { return paintArtifact().paint
Chunks(); } | |
| 120 | |
| 121 bool clientCacheIsValid(DisplayItemClient) const; | |
| 122 | |
| 123 bool displayItemConstructionIsDisabled() const { return m_constructionDisabl
ed; } | |
| 124 void setDisplayItemConstructionIsDisabled(const bool disable) { m_constructi
onDisabled = disable; } | |
| 125 | |
| 126 bool textPainted() const { return m_textPainted; } | |
| 127 void setTextPainted() { m_textPainted = true; } | |
| 128 | |
| 129 // Returns displayItems added using createAndAppend() since beginning or the
last | |
| 130 // commitNewDisplayItems(). Use with care. | |
| 131 DisplayItems& newDisplayItems() { return m_newDisplayItems; } | |
| 132 | |
| 133 #ifndef NDEBUG | |
| 134 void showDebugData() const; | |
| 135 #endif | |
| 136 | |
| 137 void startTrackingPaintInvalidationObjects() | |
| 138 { | |
| 139 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | |
| 140 m_trackedPaintInvalidationObjects = adoptPtr(new Vector<String>()); | |
| 141 } | |
| 142 void stopTrackingPaintInvalidationObjects() | |
| 143 { | |
| 144 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | |
| 145 m_trackedPaintInvalidationObjects = nullptr; | |
| 146 } | |
| 147 Vector<String> trackedPaintInvalidationObjects() | |
| 148 { | |
| 149 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | |
| 150 return m_trackedPaintInvalidationObjects ? *m_trackedPaintInvalidationOb
jects : Vector<String>(); | |
| 151 } | |
| 152 | |
| 153 bool clientHasCheckedPaintInvalidation(DisplayItemClient client) const | |
| 154 { | |
| 155 ASSERT(RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled(
)); | |
| 156 return m_clientsCheckedPaintInvalidation.contains(client); | |
| 157 } | |
| 158 void setClientHasCheckedPaintInvalidation(DisplayItemClient client) | |
| 159 { | |
| 160 ASSERT(RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled(
)); | |
| 161 m_clientsCheckedPaintInvalidation.add(client); | |
| 162 } | |
| 163 | |
| 164 protected: | |
| 165 DisplayItemList() | |
| 166 : m_newDisplayItems(kInitialDisplayItemsCapacity * kMaximumDisplayItemSi
ze) | |
| 167 , m_validlyCachedClientsDirty(false) | |
| 168 , m_constructionDisabled(false) | |
| 169 , m_textPainted(false) | |
| 170 , m_skippingCacheCount(0) | |
| 171 , m_numCachedItems(0) | |
| 172 , m_nextScope(1) { } | |
| 173 | |
| 174 private: | |
| 175 // Set new item state (scopes, cache skipping, etc) for a new item. | |
| 176 void processNewItem(DisplayItem&); | |
| 177 | |
| 178 void updateValidlyCachedClientsIfNeeded() const; | |
| 179 | |
| 180 void invalidateClient(const DisplayItemClientWrapper&); | |
| 181 | |
| 182 #ifndef NDEBUG | |
| 183 WTF::String displayItemsAsDebugString(const DisplayItems&) const; | |
| 184 #endif | |
| 185 | |
| 186 // Indices into PaintList of all DrawingDisplayItems and BeginSubsequenceDis
playItems of each client. | |
| 187 // Temporarily used during merge to find out-of-order display items. | |
| 188 using DisplayItemIndicesByClientMap = HashMap<DisplayItemClient, Vector<size
_t>>; | |
| 189 | |
| 190 static size_t findMatchingItemFromIndex(const DisplayItem::Id&, const Displa
yItemIndicesByClientMap&, const DisplayItems&); | |
| 191 static void addItemToIndexIfNeeded(const DisplayItem&, size_t index, Display
ItemIndicesByClientMap&); | |
| 192 | |
| 193 struct OutOfOrderIndexContext; | |
| 194 DisplayItems::iterator findOutOfOrderCachedItem(const DisplayItem::Id&, OutO
fOrderIndexContext&); | |
| 195 DisplayItems::iterator findOutOfOrderCachedItemForward(const DisplayItem::Id
&, OutOfOrderIndexContext&); | |
| 196 void copyCachedSubsequence(DisplayItems::iterator& currentIt, DisplayItems&
updatedList); | |
| 197 | |
| 198 #if ENABLE(ASSERT) | |
| 199 // The following two methods are for checking under-invalidations | |
| 200 // (when RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabl
ed). | |
| 201 void checkUnderInvalidation(DisplayItems::iterator& newIt, DisplayItems::ite
rator& currentIt); | |
| 202 void checkCachedDisplayItemIsUnchanged(const char* messagePrefix, const Disp
layItem& newItem, const DisplayItem& oldItem); | |
| 203 void checkNoRemainingCachedDisplayItems(); | |
| 204 #endif | |
| 205 | |
| 206 // The last complete paint artifact. | |
| 207 // In SPv2, this includes paint chunks as well as display items. | |
| 208 PaintArtifact m_currentPaintArtifact; | |
| 209 | |
| 210 // Data being used to build the next paint artifact. | |
| 211 DisplayItems m_newDisplayItems; | |
| 212 PaintChunker m_newPaintChunks; | |
| 213 | |
| 214 // Contains all clients having valid cached paintings if updated. | |
| 215 // It's lazily updated in updateValidlyCachedClientsIfNeeded(). | |
| 216 // TODO(wangxianzhu): In the future we can replace this with client-side rep
aint flags | |
| 217 // to avoid the cost of building and querying the hash table. | |
| 218 mutable HashSet<DisplayItemClient> m_validlyCachedClients; | |
| 219 mutable bool m_validlyCachedClientsDirty; | |
| 220 | |
| 221 // Used during painting. Contains clients that have checked paint invalidati
on and | |
| 222 // are known to be valid. | |
| 223 // TODO(wangxianzhu): Use client side flag to avoid const of hash table. | |
| 224 HashSet<DisplayItemClient> m_clientsCheckedPaintInvalidation; | |
| 225 | |
| 226 #if ENABLE(ASSERT) | |
| 227 // Set of clients which had paint offset changes since the last commit. This
is used for | |
| 228 // ensuring paint offsets are only updated once and are the same in all phas
es. | |
| 229 HashSet<DisplayItemClient> m_clientsWithPaintOffsetInvalidations; | |
| 230 #endif | |
| 231 | |
| 232 // Allow display item construction to be disabled to isolate the costs of co
nstruction | |
| 233 // in performance metrics. | |
| 234 bool m_constructionDisabled; | |
| 235 | |
| 236 // Indicates this DisplayItemList has ever had text. It is never reset to fa
lse. | |
| 237 bool m_textPainted; | |
| 238 | |
| 239 int m_skippingCacheCount; | |
| 240 | |
| 241 int m_numCachedItems; | |
| 242 | |
| 243 unsigned m_nextScope; | |
| 244 Vector<unsigned> m_scopeStack; | |
| 245 | |
| 246 struct Invalidation { | |
| 247 IntRect rect; | |
| 248 PaintInvalidationReason invalidationReason; | |
| 249 }; | |
| 250 | |
| 251 Vector<Invalidation> m_invalidations; | |
| 252 | |
| 253 #if ENABLE(ASSERT) | |
| 254 // This is used to check duplicated ids during add(). We could also check du
ring | |
| 255 // updatePaintList(), but checking during add() helps developer easily find
where | |
| 256 // the duplicated ids are from. | |
| 257 DisplayItemIndicesByClientMap m_newDisplayItemIndicesByClient; | |
| 258 #endif | |
| 259 | |
| 260 OwnPtr<Vector<String>> m_trackedPaintInvalidationObjects; | |
| 261 }; | |
| 262 | |
| 263 } // namespace blink | |
| 264 | |
| 265 #endif // DisplayItemList_h | |
| OLD | NEW |