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 {
// The paint properties which apply to this chunk.
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;
// True if the bounds are filled entirely with opaque contents.
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)
......@@ -87,7 +92,8 @@ inline bool operator==(const PaintChunk& a, const PaintChunk& b)
&& a.id == b.id
&& a.properties == b.properties
&& 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)
......
......@@ -18,7 +18,7 @@ PaintChunker::~PaintChunker()
void PaintChunker::updateCurrentPaintChunkProperties(const PaintChunk::Id* chunkId, const PaintChunkProperties& properties)
{
ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
m_currentChunkId = WTF::nullopt;
if (chunkId)
......@@ -26,9 +26,9 @@ void PaintChunker::updateCurrentPaintChunkProperties(const PaintChunk::Id* chunk
m_currentProperties = properties;
}
void PaintChunker::incrementDisplayItemIndex(const DisplayItem& item)
bool PaintChunker::incrementDisplayItemIndex(const DisplayItem& item)
{
ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
ItemBehavior behavior;
Optional<PaintChunk::Id> newChunkId;
......@@ -53,7 +53,7 @@ void PaintChunker::incrementDisplayItemIndex(const DisplayItem& item)
PaintChunk newChunk(0, 1, newChunkId ? &*newChunkId : nullptr, m_currentProperties);
m_chunks.append(newChunk);
m_chunkBehavior.append(behavior);
return;
return true;
}
auto& lastChunk = m_chunks.last();
......@@ -62,26 +62,29 @@ void PaintChunker::incrementDisplayItemIndex(const DisplayItem& item)
&& m_chunkBehavior.last() != RequiresSeparateChunk;
if (canContinueChunk) {
lastChunk.endIndex++;
return;
return false;
}
PaintChunk newChunk(lastChunk.endIndex, lastChunk.endIndex + 1, newChunkId ? &*newChunkId : nullptr, m_currentProperties);
m_chunks.append(newChunk);
m_chunkBehavior.append(behavior);
return true;
}
void PaintChunker::decrementDisplayItemIndex()
bool PaintChunker::decrementDisplayItemIndex()
{
ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
ASSERT(!m_chunks.isEmpty());
DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
DCHECK(!m_chunks.isEmpty());
auto& lastChunk = m_chunks.last();
if ((lastChunk.endIndex - lastChunk.beginIndex) > 1) {
lastChunk.endIndex--;
} else {
m_chunks.removeLast();
m_chunkBehavior.removeLast();
return false;
}
m_chunks.removeLast();
m_chunkBehavior.removeLast();
return true;
}
void PaintChunker::clear()
......
......@@ -30,10 +30,14 @@ public:
const PaintChunkProperties& currentPaintChunkProperties() const { return m_currentProperties; }
void updateCurrentPaintChunkProperties(const PaintChunk::Id*, const PaintChunkProperties&);
void incrementDisplayItemIndex(const DisplayItem&);
void decrementDisplayItemIndex();
// Returns true if a new chunk is created.
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();
......
......@@ -78,7 +78,7 @@ public:
ensureNewDisplayItemListInitialCapacity();
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
......@@ -164,6 +164,7 @@ protected:
, m_imagePainted(false)
, m_skippingCacheCount(0)
, m_numCachedNewItems(0)
, m_currentChunkIsFromCachedSubsequence(true)
#if DCHECK_IS_ON()
, m_numSequentialMatches(0)
, m_numOutOfOrderMatches(0)
......@@ -186,16 +187,16 @@ private:
}
// 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;
// Indices into PaintList of all DrawingDisplayItems and BeginSubsequenceDisplayItems of each client.
// Temporarily used during merge to find out-of-order display items.
using DisplayItemIndicesByClientMap = HashMap<const DisplayItemClient*, Vector<size_t>>;
// Maps clients to indices of display items or chunks of each client.
using IndicesByClientMap = HashMap<const DisplayItemClient*, Vector<size_t>>;
static size_t findMatchingItemFromIndex(const DisplayItem::Id&, const DisplayItemIndicesByClientMap&, const DisplayItemList&);
static void addItemToIndexIfNeeded(const DisplayItem&, size_t index, DisplayItemIndicesByClientMap&);
static size_t findMatchingItemFromIndex(const DisplayItem::Id&, const IndicesByClientMap&, const DisplayItemList&);
static void addItemToIndexIfNeeded(const DisplayItem&, size_t index, IndicesByClientMap&);
size_t findCachedItem(const DisplayItem::Id&);
size_t findOutOfOrderCachedItemForward(const DisplayItem::Id&);
......@@ -206,6 +207,9 @@ private:
// is newly created, or is changed causing the previous indices to be invalid.
void resetCurrentListIndices();
void generateChunkRasterInvalidationRects(PaintChunk& newChunk);
void generateChunkRasterInvalidationRectsComparingOldChunk(PaintChunk& newChunk, const PaintChunk& oldChunk);
#if DCHECK_IS_ON()
// The following two methods are for checking under-invalidations
// (when RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled).
......@@ -237,13 +241,14 @@ private:
int m_numCachedNewItems;
// Stores indices to valid DrawingDisplayItems in current display list that have not been
// matched by CachedDisplayItems during sequential matching. The indexed items will be
// Stores indices to valid cacheable display items in m_currentPaintArtifact.displayItemList()
// 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
// 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
// algorithm runs in linear time.
DisplayItemIndicesByClientMap m_outOfOrderItemIndices;
IndicesByClientMap m_outOfOrderItemIndices;
// The next item in the current list for sequential match.
size_t m_nextItemToMatch;
......@@ -251,6 +256,14 @@ private:
// The next item in the current list to be indexed for out-of-order cache requests.
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;
#if DCHECK_IS_ON()
......@@ -259,7 +272,7 @@ private:
int m_numIndexedItems;
// This is used to check duplicated ids during createAndAppend().
DisplayItemIndicesByClientMap m_newDisplayItemIndicesByClient;
IndicesByClientMap m_newDisplayItemIndicesByClient;
// These are set in useCachedDrawingIfPossible() and useCachedSubsequenceIfPossible()
// when we could use cached drawing or subsequence and under-invalidation checking is on,
......
......@@ -20,6 +20,8 @@ public:
String debugName() const final { return m_name; }
LayoutRect visualRect() const override { return m_visualRect; }
void setVisualRect(const LayoutRect& r) { m_visualRect = r; }
// This simulates a paint without needing a PaintController.
void updateCacheGeneration()
{
......
......@@ -62,6 +62,16 @@ void PrintTo(const PaintChunk& chunk, std::ostream* os)
*os << ", bounds=";
PrintTo(chunk.bounds, os);
*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)
......
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