Commit 0a848fcd authored by wangxianzhu's avatar wangxianzhu Committed by Commit bot

[SPv2] Rasterization invalidation

Design doc: https://docs.google.com/document/d/1M669yu7nsF9Wrkm7nQFi3Pp2r-QmCMqm4K7fPPo-doA/edit#heading=h.t80gaiwoyk1m

This will replace ObjectPaintInvalidator::invalidateUsingContainer()
for SPv2.

CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
BUG=510908

Review-Url: https://codereview.chromium.org/2277443003
Cr-Commit-Position: refs/heads/master@{#414835}
parent 4dab4621
...@@ -73,11 +73,16 @@ struct PaintChunk { ...@@ -73,11 +73,16 @@ struct PaintChunk {
// The paint properties which apply to this chunk. // The paint properties which apply to this chunk.
PaintChunkProperties properties; PaintChunkProperties properties;
// The total bounds of this paint chunk's contents. // The total bounds of this paint chunk's contents, in -the coordinate space of
// the containing transform node.
FloatRect bounds; FloatRect bounds;
// True if the bounds are filled entirely with opaque contents. // True if the bounds are filled entirely with opaque contents.
bool knownToBeOpaque; bool knownToBeOpaque;
// SPv2 only. Rectangles that need to be re-rasterized in this chunk, in the
// coordinate space of the containing transform node.
Vector<FloatRect> rasterInvalidationRects;
}; };
inline bool operator==(const PaintChunk& a, const PaintChunk& b) inline bool operator==(const PaintChunk& a, const PaintChunk& b)
...@@ -87,7 +92,8 @@ inline bool operator==(const PaintChunk& a, const PaintChunk& b) ...@@ -87,7 +92,8 @@ inline bool operator==(const PaintChunk& a, const PaintChunk& b)
&& a.id == b.id && a.id == b.id
&& a.properties == b.properties && a.properties == b.properties
&& a.bounds == b.bounds && a.bounds == b.bounds
&& a.knownToBeOpaque == b.knownToBeOpaque; && a.knownToBeOpaque == b.knownToBeOpaque
&& a.rasterInvalidationRects == b.rasterInvalidationRects;
} }
inline bool operator!=(const PaintChunk& a, const PaintChunk& b) inline bool operator!=(const PaintChunk& a, const PaintChunk& b)
......
...@@ -18,7 +18,7 @@ PaintChunker::~PaintChunker() ...@@ -18,7 +18,7 @@ PaintChunker::~PaintChunker()
void PaintChunker::updateCurrentPaintChunkProperties(const PaintChunk::Id* chunkId, const PaintChunkProperties& properties) void PaintChunker::updateCurrentPaintChunkProperties(const PaintChunk::Id* chunkId, const PaintChunkProperties& properties)
{ {
ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
m_currentChunkId = WTF::nullopt; m_currentChunkId = WTF::nullopt;
if (chunkId) if (chunkId)
...@@ -26,9 +26,9 @@ void PaintChunker::updateCurrentPaintChunkProperties(const PaintChunk::Id* chunk ...@@ -26,9 +26,9 @@ void PaintChunker::updateCurrentPaintChunkProperties(const PaintChunk::Id* chunk
m_currentProperties = properties; m_currentProperties = properties;
} }
void PaintChunker::incrementDisplayItemIndex(const DisplayItem& item) bool PaintChunker::incrementDisplayItemIndex(const DisplayItem& item)
{ {
ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
ItemBehavior behavior; ItemBehavior behavior;
Optional<PaintChunk::Id> newChunkId; Optional<PaintChunk::Id> newChunkId;
...@@ -53,7 +53,7 @@ void PaintChunker::incrementDisplayItemIndex(const DisplayItem& item) ...@@ -53,7 +53,7 @@ void PaintChunker::incrementDisplayItemIndex(const DisplayItem& item)
PaintChunk newChunk(0, 1, newChunkId ? &*newChunkId : nullptr, m_currentProperties); PaintChunk newChunk(0, 1, newChunkId ? &*newChunkId : nullptr, m_currentProperties);
m_chunks.append(newChunk); m_chunks.append(newChunk);
m_chunkBehavior.append(behavior); m_chunkBehavior.append(behavior);
return; return true;
} }
auto& lastChunk = m_chunks.last(); auto& lastChunk = m_chunks.last();
...@@ -62,26 +62,29 @@ void PaintChunker::incrementDisplayItemIndex(const DisplayItem& item) ...@@ -62,26 +62,29 @@ void PaintChunker::incrementDisplayItemIndex(const DisplayItem& item)
&& m_chunkBehavior.last() != RequiresSeparateChunk; && m_chunkBehavior.last() != RequiresSeparateChunk;
if (canContinueChunk) { if (canContinueChunk) {
lastChunk.endIndex++; lastChunk.endIndex++;
return; return false;
} }
PaintChunk newChunk(lastChunk.endIndex, lastChunk.endIndex + 1, newChunkId ? &*newChunkId : nullptr, m_currentProperties); PaintChunk newChunk(lastChunk.endIndex, lastChunk.endIndex + 1, newChunkId ? &*newChunkId : nullptr, m_currentProperties);
m_chunks.append(newChunk); m_chunks.append(newChunk);
m_chunkBehavior.append(behavior); m_chunkBehavior.append(behavior);
return true;
} }
void PaintChunker::decrementDisplayItemIndex() bool PaintChunker::decrementDisplayItemIndex()
{ {
ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
ASSERT(!m_chunks.isEmpty()); DCHECK(!m_chunks.isEmpty());
auto& lastChunk = m_chunks.last(); auto& lastChunk = m_chunks.last();
if ((lastChunk.endIndex - lastChunk.beginIndex) > 1) { if ((lastChunk.endIndex - lastChunk.beginIndex) > 1) {
lastChunk.endIndex--; lastChunk.endIndex--;
} else { return false;
m_chunks.removeLast();
m_chunkBehavior.removeLast();
} }
m_chunks.removeLast();
m_chunkBehavior.removeLast();
return true;
} }
void PaintChunker::clear() void PaintChunker::clear()
......
...@@ -30,10 +30,14 @@ public: ...@@ -30,10 +30,14 @@ public:
const PaintChunkProperties& currentPaintChunkProperties() const { return m_currentProperties; } const PaintChunkProperties& currentPaintChunkProperties() const { return m_currentProperties; }
void updateCurrentPaintChunkProperties(const PaintChunk::Id*, const PaintChunkProperties&); void updateCurrentPaintChunkProperties(const PaintChunk::Id*, const PaintChunkProperties&);
void incrementDisplayItemIndex(const DisplayItem&); // Returns true if a new chunk is created.
void decrementDisplayItemIndex(); bool incrementDisplayItemIndex(const DisplayItem&);
// Returns true if the last chunk is removed.
bool decrementDisplayItemIndex();
const PaintChunk& lastChunk() const { return m_chunks.last(); } PaintChunk& paintChunkAt(size_t i) { return m_chunks[i]; }
size_t lastChunkIndex() const { return m_chunks.isEmpty() ? kNotFound : m_chunks.size() - 1; }
PaintChunk& lastChunk() { return m_chunks.last(); }
void clear(); void clear();
......
...@@ -78,7 +78,7 @@ public: ...@@ -78,7 +78,7 @@ public:
ensureNewDisplayItemListInitialCapacity(); ensureNewDisplayItemListInitialCapacity();
DisplayItemClass& displayItem = m_newDisplayItemList.allocateAndConstruct<DisplayItemClass>(std::forward<Args>(args)...); DisplayItemClass& displayItem = m_newDisplayItemList.allocateAndConstruct<DisplayItemClass>(std::forward<Args>(args)...);
processNewItem(displayItem); processNewItem(displayItem, NewPainting);
} }
// Creates and appends an ending display item to pair with a preceding // Creates and appends an ending display item to pair with a preceding
...@@ -164,6 +164,7 @@ protected: ...@@ -164,6 +164,7 @@ protected:
, m_imagePainted(false) , m_imagePainted(false)
, m_skippingCacheCount(0) , m_skippingCacheCount(0)
, m_numCachedNewItems(0) , m_numCachedNewItems(0)
, m_currentChunkIsFromCachedSubsequence(true)
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
, m_numSequentialMatches(0) , m_numSequentialMatches(0)
, m_numOutOfOrderMatches(0) , m_numOutOfOrderMatches(0)
...@@ -186,16 +187,16 @@ private: ...@@ -186,16 +187,16 @@ private:
} }
// Set new item state (cache skipping, etc) for a new item. // Set new item state (cache skipping, etc) for a new item.
void processNewItem(DisplayItem&); enum NewItemSource { FromCachedItem, FromCachedSubsequence, NewPainting };
void processNewItem(DisplayItem&, NewItemSource);
String displayItemListAsDebugString(const DisplayItemList&) const; String displayItemListAsDebugString(const DisplayItemList&) const;
// Indices into PaintList of all DrawingDisplayItems and BeginSubsequenceDisplayItems of each client. // Maps clients to indices of display items or chunks of each client.
// Temporarily used during merge to find out-of-order display items. using IndicesByClientMap = HashMap<const DisplayItemClient*, Vector<size_t>>;
using DisplayItemIndicesByClientMap = HashMap<const DisplayItemClient*, Vector<size_t>>;
static size_t findMatchingItemFromIndex(const DisplayItem::Id&, const DisplayItemIndicesByClientMap&, const DisplayItemList&); static size_t findMatchingItemFromIndex(const DisplayItem::Id&, const IndicesByClientMap&, const DisplayItemList&);
static void addItemToIndexIfNeeded(const DisplayItem&, size_t index, DisplayItemIndicesByClientMap&); static void addItemToIndexIfNeeded(const DisplayItem&, size_t index, IndicesByClientMap&);
size_t findCachedItem(const DisplayItem::Id&); size_t findCachedItem(const DisplayItem::Id&);
size_t findOutOfOrderCachedItemForward(const DisplayItem::Id&); size_t findOutOfOrderCachedItemForward(const DisplayItem::Id&);
...@@ -206,6 +207,9 @@ private: ...@@ -206,6 +207,9 @@ private:
// is newly created, or is changed causing the previous indices to be invalid. // is newly created, or is changed causing the previous indices to be invalid.
void resetCurrentListIndices(); void resetCurrentListIndices();
void generateChunkRasterInvalidationRects(PaintChunk& newChunk);
void generateChunkRasterInvalidationRectsComparingOldChunk(PaintChunk& newChunk, const PaintChunk& oldChunk);
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
// The following two methods are for checking under-invalidations // The following two methods are for checking under-invalidations
// (when RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled). // (when RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled).
...@@ -237,13 +241,14 @@ private: ...@@ -237,13 +241,14 @@ private:
int m_numCachedNewItems; int m_numCachedNewItems;
// Stores indices to valid DrawingDisplayItems in current display list that have not been // Stores indices to valid cacheable display items in m_currentPaintArtifact.displayItemList()
// matched by CachedDisplayItems during sequential matching. The indexed items will be // that have not been matched by requests of cached display items (using useCachedDrawingIfPossible()
// and useCachedSubsequenceIfPossible()) during sequential matching . The indexed items will be
// matched by later out-of-order requests of cached display items. This ensures that when // matched by later out-of-order requests of cached display items. This ensures that when
// out-of-order cached display items are requested, we only traverse at most once over // out-of-order cached display items are requested, we only traverse at most once over
// the current display list looking for potential matches. Thus we can ensure that the // the current display list looking for potential matches. Thus we can ensure that the
// algorithm runs in linear time. // algorithm runs in linear time.
DisplayItemIndicesByClientMap m_outOfOrderItemIndices; IndicesByClientMap m_outOfOrderItemIndices;
// The next item in the current list for sequential match. // The next item in the current list for sequential match.
size_t m_nextItemToMatch; size_t m_nextItemToMatch;
...@@ -251,6 +256,14 @@ private: ...@@ -251,6 +256,14 @@ private:
// The next item in the current list to be indexed for out-of-order cache requests. // The next item in the current list to be indexed for out-of-order cache requests.
size_t m_nextItemToIndex; size_t m_nextItemToIndex;
// Similar to m_outOfOrderItemIndices but
// - the indices are chunk indices in m_currentPaintArtifacts.paintChunks();
// - chunks are matched not only for requests of cached display items, but also non-cached display items.
IndicesByClientMap m_outOfOrderChunkIndices;
bool m_currentChunkIsFromCachedSubsequence;
size_t m_nextChunkToMatch;
DisplayItemClient::CacheGenerationOrInvalidationReason m_currentCacheGeneration; DisplayItemClient::CacheGenerationOrInvalidationReason m_currentCacheGeneration;
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
...@@ -259,7 +272,7 @@ private: ...@@ -259,7 +272,7 @@ private:
int m_numIndexedItems; int m_numIndexedItems;
// This is used to check duplicated ids during createAndAppend(). // This is used to check duplicated ids during createAndAppend().
DisplayItemIndicesByClientMap m_newDisplayItemIndicesByClient; IndicesByClientMap m_newDisplayItemIndicesByClient;
// These are set in useCachedDrawingIfPossible() and useCachedSubsequenceIfPossible() // These are set in useCachedDrawingIfPossible() and useCachedSubsequenceIfPossible()
// when we could use cached drawing or subsequence and under-invalidation checking is on, // when we could use cached drawing or subsequence and under-invalidation checking is on,
......
...@@ -20,6 +20,8 @@ public: ...@@ -20,6 +20,8 @@ public:
String debugName() const final { return m_name; } String debugName() const final { return m_name; }
LayoutRect visualRect() const override { return m_visualRect; } LayoutRect visualRect() const override { return m_visualRect; }
void setVisualRect(const LayoutRect& r) { m_visualRect = r; }
// This simulates a paint without needing a PaintController. // This simulates a paint without needing a PaintController.
void updateCacheGeneration() void updateCacheGeneration()
{ {
......
...@@ -62,6 +62,16 @@ void PrintTo(const PaintChunk& chunk, std::ostream* os) ...@@ -62,6 +62,16 @@ void PrintTo(const PaintChunk& chunk, std::ostream* os)
*os << ", bounds="; *os << ", bounds=";
PrintTo(chunk.bounds, os); PrintTo(chunk.bounds, os);
*os << ", knownToBeOpaque=" << chunk.knownToBeOpaque << ")"; *os << ", knownToBeOpaque=" << chunk.knownToBeOpaque << ")";
*os << ", rerasterizationRects=[";
bool first = true;
for (auto& r : chunk.rasterInvalidationRects) {
if (!first)
*os << ", ";
first = false;
PrintTo(r, os);
};
*os << "]";
} }
void PrintTo(const PaintChunkProperties& properties, std::ostream* os) void PrintTo(const PaintChunkProperties& properties, std::ostream* os)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment