Revert of PaintChunk::id (patchset #10 id:180001 of https://codereview.chromium.org/2116693002/ )
Reason for revert: Test failures on WebKit Win x64 Builder (dbg) since https://build.chromium.org/p/chromium.webkit/builders/WebKit%20Win%20x64%20Builder%20%28dbg%29/builds/89039. failures: PaintChunkerTest.BuildChunksFromNestedTransforms PaintChunkerTest.ChangingPropertiesWithoutItems PaintChunkerTest.SingleNonEmptyRange PaintChunkerTest.CreatesSeparateChunksWhenRequested PaintChunkerTest.ChunkIds PaintChunkerTest.SamePropertiesTwiceCombineIntoOneChunk PaintChunkerTest.ChunkIdsSkippingCache PaintChunkerTest.BuildMultipleChunksWithSinglePropertyChanging PaintChunkerTest.CanRewindDisplayItemIndex PaintChunkerTest.BuildMultipleChunksWithDifferentPropertyChanges Original issue's description: > PaintChunk::id > > The id will be used in rasterization paint invalidation to match old > and new paint chunks. It can be also used in incremental layerization. > > BUG=510908 > > Committed: https://crrev.com/5426e435a6a1c6761b7d9565f769fcde10e7b99c > Cr-Commit-Position: refs/heads/master@{#406461} TBR=chrishtr@chromium.org,pdr@chromium.org,wangxianzhu@chromium.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=510908 Review-Url: https://codereview.chromium.org/2161253003 Cr-Commit-Position: refs/heads/master@{#406479}
This commit is contained in:
third_party/WebKit/Source
core
frame
paint
platform
@ -106,7 +106,6 @@
|
||||
#include "platform/graphics/GraphicsLayerDebugInfo.h"
|
||||
#include "platform/graphics/paint/CullRect.h"
|
||||
#include "platform/graphics/paint/PaintController.h"
|
||||
#include "platform/graphics/paint/ScopedPaintChunkProperties.h"
|
||||
#include "platform/scheduler/CancellableTaskFactory.h"
|
||||
#include "platform/scroll/ScrollAnimatorBase.h"
|
||||
#include "platform/scroll/ScrollbarTheme.h"
|
||||
@ -2643,15 +2642,16 @@ void FrameView::synchronizedPaintRecursively(GraphicsLayer* graphicsLayer)
|
||||
// Usually this is not needed because the PaintLayer will setup the chunk properties
|
||||
// altogether. However in debug builds the GraphicsLayer could paint debug background before
|
||||
// we ever reach the PaintLayer.
|
||||
Optional<ScopedPaintChunkProperties> scopedPaintChunkProperties;
|
||||
if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
|
||||
PaintChunkProperties properties;
|
||||
properties.transform = m_rootTransform;
|
||||
properties.clip = m_rootClip;
|
||||
properties.effect = m_rootEffect;
|
||||
scopedPaintChunkProperties.emplace(graphicsLayer->getPaintController(), *layoutView(), DisplayItem::DebugRedFill, properties);
|
||||
graphicsLayer->getPaintController().updateCurrentPaintChunkProperties(properties);
|
||||
}
|
||||
graphicsLayer->paint(nullptr);
|
||||
if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
|
||||
graphicsLayer->getPaintController().updateCurrentPaintChunkProperties(PaintChunkProperties());
|
||||
}
|
||||
|
||||
if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
|
||||
|
@ -161,7 +161,7 @@ void BlockPainter::paintObject(const PaintInfo& paintInfo, const LayoutPoint& pa
|
||||
if (auto* scrollTranslation = objectProperties ? objectProperties->scrollTranslation() : nullptr) {
|
||||
PaintChunkProperties properties(paintInfo.context.getPaintController().currentPaintChunkProperties());
|
||||
properties.transform = scrollTranslation;
|
||||
m_scopedScrollProperty.emplace(paintInfo.context.getPaintController(), m_layoutBlock, DisplayItem::paintPhaseToDrawingType(paintPhase), properties);
|
||||
m_scopedScrollProperty.emplace(paintInfo.context.getPaintController(), properties);
|
||||
scrolledPaintInfo.emplace(paintInfo);
|
||||
scrolledPaintInfo->updateCullRect(scrollTranslation->matrix().toAffineTransform());
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ BoxClipper::BoxClipper(const LayoutBox& box, const PaintInfo& paintInfo, const L
|
||||
if (objectProperties && objectProperties->overflowClip()) {
|
||||
PaintChunkProperties properties(paintInfo.context.getPaintController().currentPaintChunkProperties());
|
||||
properties.clip = objectProperties->overflowClip();
|
||||
m_scopedClipProperty.emplace(paintInfo.context.getPaintController(), box, paintInfo.displayItemTypeForClipping(), properties);
|
||||
m_scopedClipProperty.emplace(paintInfo.context.getPaintController(), properties);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ void FramePainter::paint(GraphicsContext& context, const GlobalPaintFlags global
|
||||
properties.transform = transform;
|
||||
if (clip)
|
||||
properties.clip = clip;
|
||||
scopedPaintChunkProperties.emplace(context.getPaintController(), *frameView().layoutView(), properties);
|
||||
scopedPaintChunkProperties.emplace(context.getPaintController(), properties);
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ void FramePainter::paint(GraphicsContext& context, const GlobalPaintFlags global
|
||||
if (TransformPaintPropertyNode* transform = m_frameView->preTranslation()) {
|
||||
PaintChunkProperties properties(context.getPaintController().currentPaintChunkProperties());
|
||||
properties.transform = transform;
|
||||
scopedPaintChunkProperties.emplace(context.getPaintController(), *frameView().layoutView(), properties);
|
||||
scopedPaintChunkProperties.emplace(context.getPaintController(), properties);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,7 +378,7 @@ PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContents(GraphicsCon
|
||||
properties.clip = localBorderBoxProperties.propertyTreeState.clip;
|
||||
properties.effect = localBorderBoxProperties.propertyTreeState.effect;
|
||||
properties.backfaceHidden = m_paintLayer.layoutObject()->hasHiddenBackface();
|
||||
scopedPaintChunkProperties.emplace(context.getPaintController(), m_paintLayer, properties);
|
||||
scopedPaintChunkProperties.emplace(context.getPaintController(), properties);
|
||||
}
|
||||
|
||||
bool shouldPaintBackground = isPaintingCompositedBackground && shouldPaintContent && !selectionOnly;
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
auto& paintController = context.getPaintController();
|
||||
PaintChunkProperties properties(paintController.currentPaintChunkProperties());
|
||||
properties.transform = objectProperties->svgLocalToBorderBoxTransform();
|
||||
m_transformPropertyScope.emplace(paintController, object, properties);
|
||||
m_transformPropertyScope.emplace(paintController, properties);
|
||||
}
|
||||
} else {
|
||||
DCHECK(object.isSVG());
|
||||
@ -77,7 +77,7 @@ public:
|
||||
auto& paintController = context.getPaintController();
|
||||
PaintChunkProperties properties(paintController.currentPaintChunkProperties());
|
||||
properties.transform = objectProperties->transform();
|
||||
m_transformPropertyScope.emplace(paintController, object, properties);
|
||||
m_transformPropertyScope.emplace(paintController, properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ void ScrollableAreaPainter::paintOverflowControls(GraphicsContext& context, cons
|
||||
if (objectProperties && objectProperties->scrollbarPaintOffset()) {
|
||||
PaintChunkProperties properties(context.getPaintController().currentPaintChunkProperties());
|
||||
properties.transform = objectProperties->scrollbarPaintOffset();
|
||||
scopedTransformProperty.emplace(context.getPaintController(), getScrollableArea().box(), DisplayItem::ScrollOverflowControls, properties);
|
||||
scopedTransformProperty.emplace(context.getPaintController(), properties);
|
||||
}
|
||||
}
|
||||
if (getScrollableArea().horizontalScrollbar() && !getScrollableArea().layerForHorizontalScrollbar()) {
|
||||
|
@ -1216,7 +1216,6 @@
|
||||
'graphics/paint/DisplayItemTest.cpp',
|
||||
'graphics/paint/GeometryMapperTest.cpp',
|
||||
'graphics/paint/PaintArtifactToSkCanvasTest.cpp',
|
||||
'graphics/paint/PaintChunkTest.cpp',
|
||||
'graphics/paint/PaintChunkerTest.cpp',
|
||||
'graphics/paint/PaintControllerTest.cpp',
|
||||
'graphics/paint/PropertyTreeStateTest.cpp',
|
||||
|
@ -215,7 +215,7 @@ public:
|
||||
|
||||
// Ids are for matching new DisplayItems with existing DisplayItems.
|
||||
struct Id {
|
||||
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
|
||||
STACK_ALLOCATED();
|
||||
Id(const DisplayItemClient& client, const Type type)
|
||||
: client(client)
|
||||
, type(type) { }
|
||||
|
@ -63,11 +63,7 @@ public:
|
||||
|
||||
PaintInvalidationReason getPaintInvalidationReason() const { return m_cacheGenerationOrInvalidationReason.getPaintInvalidationReason(); }
|
||||
|
||||
// A client is considered "just created" if its display items have never been committed.
|
||||
bool isJustCreated() const { return m_cacheGenerationOrInvalidationReason.isJustCreated(); }
|
||||
|
||||
private:
|
||||
friend class FakeDisplayItemClient;
|
||||
friend class PaintController;
|
||||
|
||||
// Holds a unique cache generation id of DisplayItemClients and PaintControllers,
|
||||
@ -85,16 +81,12 @@ private:
|
||||
// only. The client will be treated as invalid on other paint controllers regardless if
|
||||
// it's validly cached by these paint controllers. The situation is very rare (about 0.07%
|
||||
// clients were painted on multiple paint controllers) so the performance penalty is trivial.
|
||||
class PLATFORM_EXPORT CacheGenerationOrInvalidationReason {
|
||||
class CacheGenerationOrInvalidationReason {
|
||||
DISALLOW_NEW();
|
||||
public:
|
||||
CacheGenerationOrInvalidationReason() : m_value(kJustCreated) { }
|
||||
CacheGenerationOrInvalidationReason() { invalidate(); }
|
||||
|
||||
void invalidate(PaintInvalidationReason reason = PaintInvalidationFull)
|
||||
{
|
||||
if (m_value != kJustCreated)
|
||||
m_value = static_cast<ValueType>(reason);
|
||||
}
|
||||
void invalidate(PaintInvalidationReason reason = PaintInvalidationFull) { m_value = static_cast<ValueType>(reason); }
|
||||
|
||||
static CacheGenerationOrInvalidationReason next()
|
||||
{
|
||||
@ -111,17 +103,14 @@ private:
|
||||
|
||||
PaintInvalidationReason getPaintInvalidationReason() const
|
||||
{
|
||||
return m_value < kJustCreated ? static_cast<PaintInvalidationReason>(m_value) : PaintInvalidationNone;
|
||||
return m_value < kFirstValidGeneration ? static_cast<PaintInvalidationReason>(m_value) : PaintInvalidationNone;
|
||||
}
|
||||
|
||||
bool isJustCreated() const { return m_value == kJustCreated; }
|
||||
|
||||
private:
|
||||
typedef uint32_t ValueType;
|
||||
explicit CacheGenerationOrInvalidationReason(ValueType value) : m_value(value) { }
|
||||
|
||||
static const ValueType kJustCreated = static_cast<ValueType>(PaintInvalidationReasonMax) + 1;
|
||||
static const ValueType kFirstValidGeneration = static_cast<ValueType>(PaintInvalidationReasonMax) + 2;
|
||||
static const ValueType kFirstValidGeneration = static_cast<ValueType>(PaintInvalidationReasonMax) + 1;
|
||||
static ValueType s_nextGeneration;
|
||||
ValueType m_value;
|
||||
};
|
||||
|
@ -6,10 +6,8 @@
|
||||
#define PaintChunk_h
|
||||
|
||||
#include "platform/geometry/FloatRect.h"
|
||||
#include "platform/graphics/paint/DisplayItem.h"
|
||||
#include "platform/graphics/paint/PaintChunkProperties.h"
|
||||
#include "wtf/Allocator.h"
|
||||
#include "wtf/Optional.h"
|
||||
#include <iosfwd>
|
||||
|
||||
namespace blink {
|
||||
@ -23,12 +21,8 @@ namespace blink {
|
||||
struct PaintChunk {
|
||||
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
|
||||
PaintChunk() : beginIndex(0), endIndex(0), knownToBeOpaque(false) { }
|
||||
PaintChunk(unsigned begin, unsigned end, const DisplayItem::Id* chunkId, const PaintChunkProperties& props)
|
||||
: beginIndex(begin), endIndex(end), properties(props), knownToBeOpaque(false)
|
||||
{
|
||||
if (chunkId)
|
||||
id.emplace(*chunkId);
|
||||
}
|
||||
PaintChunk(unsigned begin, unsigned end, const PaintChunkProperties& props)
|
||||
: beginIndex(begin), endIndex(end), properties(props), knownToBeOpaque(false) { }
|
||||
|
||||
unsigned size() const
|
||||
{
|
||||
@ -36,24 +30,6 @@ struct PaintChunk {
|
||||
return endIndex - beginIndex;
|
||||
}
|
||||
|
||||
// Check if a new PaintChunk (this) created in the latest paint matches an old
|
||||
// PaintChunk created in the previous paint.
|
||||
bool matches(const PaintChunk& old) const
|
||||
{
|
||||
// A PaintChunk without an id doesn't match any other PaintChunks.
|
||||
if (!id || !old.id)
|
||||
return false;
|
||||
if (*id != *old.id)
|
||||
return false;
|
||||
#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
|
||||
CHECK(id->client.isAlive());
|
||||
#endif
|
||||
// A chunk whose client is just created should not match any cached chunk,
|
||||
// even if it's id equals the old chunk's id (which may happen if this chunk's
|
||||
// client is just created at the same address of the old chunk's deleted client).
|
||||
return !id->client.isJustCreated();
|
||||
}
|
||||
|
||||
// Index of the first drawing in this chunk.
|
||||
unsigned beginIndex;
|
||||
|
||||
@ -61,15 +37,6 @@ struct PaintChunk {
|
||||
// |endIndex - beginIndex| drawings in the chunk.
|
||||
unsigned endIndex;
|
||||
|
||||
// Identifier of this chunk. If it has a value, it should be unique.
|
||||
// It's used to match a new chunk to a cached old chunk to track changes of chunk
|
||||
// contents, so the id should be stable across document cycles.
|
||||
// If the contents of the chunk can't be cached (e.g. it's created when PaintController
|
||||
// is skipping cache, normally because display items can't be uniquely identified),
|
||||
// id is nullopt so that the chunk won't match any other chunk.
|
||||
using Id = DisplayItem::Id;
|
||||
Optional<Id> id;
|
||||
|
||||
// The paint properties which apply to this chunk.
|
||||
PaintChunkProperties properties;
|
||||
|
||||
@ -84,7 +51,6 @@ inline bool operator==(const PaintChunk& a, const PaintChunk& b)
|
||||
{
|
||||
return a.beginIndex == b.beginIndex
|
||||
&& a.endIndex == b.endIndex
|
||||
&& a.id == b.id
|
||||
&& a.properties == b.properties
|
||||
&& a.bounds == b.bounds
|
||||
&& a.knownToBeOpaque == b.knownToBeOpaque;
|
||||
|
@ -1,86 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "platform/graphics/paint/PaintChunk.h"
|
||||
|
||||
#include "platform/RuntimeEnabledFeatures.h"
|
||||
#include "platform/testing/FakeDisplayItemClient.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "wtf/Optional.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
TEST(PaintChunkTest, matchesSame)
|
||||
{
|
||||
PaintChunkProperties properties;
|
||||
FakeDisplayItemClient client;
|
||||
client.updateCacheGeneration();
|
||||
DisplayItem::Id id(client, DisplayItem::DrawingFirst);
|
||||
EXPECT_TRUE(PaintChunk(0, 1, &id, properties).matches(PaintChunk(0, 1, &id, properties)));
|
||||
}
|
||||
|
||||
TEST(PaintChunkTest, matchesEqual)
|
||||
{
|
||||
PaintChunkProperties properties;
|
||||
FakeDisplayItemClient client;
|
||||
client.updateCacheGeneration();
|
||||
DisplayItem::Id id(client, DisplayItem::DrawingFirst);
|
||||
DisplayItem::Id idEqual = id;
|
||||
EXPECT_TRUE(PaintChunk(0, 1, &id, properties).matches(PaintChunk(0, 1, &idEqual, properties)));
|
||||
EXPECT_TRUE(PaintChunk(0, 1, &idEqual, properties).matches(PaintChunk(0, 1, &id, properties)));
|
||||
}
|
||||
|
||||
TEST(PaintChunkTest, IdNotMatches)
|
||||
{
|
||||
PaintChunkProperties properties;
|
||||
FakeDisplayItemClient client1;
|
||||
client1.updateCacheGeneration();
|
||||
DisplayItem::Id id1a(client1, DisplayItem::DrawingFirst);
|
||||
DisplayItem::Id id1b(client1, DisplayItem::Subsequence);
|
||||
EXPECT_FALSE(PaintChunk(0, 1, &id1a, properties).matches(PaintChunk(0, 1, &id1b, properties)));
|
||||
EXPECT_FALSE(PaintChunk(0, 1, &id1b, properties).matches(PaintChunk(0, 1, &id1a, properties)));
|
||||
|
||||
FakeDisplayItemClient client2;
|
||||
client2.updateCacheGeneration();
|
||||
DisplayItem::Id id2(client2, DisplayItem::DrawingFirst);
|
||||
EXPECT_FALSE(PaintChunk(0, 1, &id1a, properties).matches(PaintChunk(0, 1, &id2, properties)));
|
||||
EXPECT_FALSE(PaintChunk(0, 1, &id2, properties).matches(PaintChunk(0, 1, &id1a, properties)));
|
||||
}
|
||||
|
||||
TEST(PaintChunkTest, IdNotMatchesNull)
|
||||
{
|
||||
PaintChunkProperties properties;
|
||||
FakeDisplayItemClient client;
|
||||
client.updateCacheGeneration();
|
||||
DisplayItem::Id id(client, DisplayItem::DrawingFirst);
|
||||
EXPECT_FALSE(PaintChunk(0, 1, nullptr, properties).matches(PaintChunk(0, 1, &id, properties)));
|
||||
EXPECT_FALSE(PaintChunk(0, 1, &id, properties).matches(PaintChunk(0, 1, nullptr, properties)));
|
||||
EXPECT_FALSE(PaintChunk(0, 1, nullptr, properties).matches(PaintChunk(0, 1, nullptr, properties)));
|
||||
}
|
||||
|
||||
TEST(PaintChunkTest, IdNotMatchesJustCreated)
|
||||
{
|
||||
PaintChunkProperties properties;
|
||||
Optional<FakeDisplayItemClient> client;
|
||||
client.emplace();
|
||||
EXPECT_TRUE(client->isJustCreated());
|
||||
// Invalidation won't change the "just created" status.
|
||||
client->setDisplayItemsUncached();
|
||||
EXPECT_TRUE(client->isJustCreated());
|
||||
|
||||
DisplayItem::Id id(*client, DisplayItem::DrawingFirst);
|
||||
// A chunk of a newly created client doesn't match any chunk because it's never cached.
|
||||
EXPECT_FALSE(PaintChunk(0, 1, &id, properties).matches(PaintChunk(0, 1, &id, properties)));
|
||||
|
||||
client->updateCacheGeneration();
|
||||
EXPECT_TRUE(PaintChunk(0, 1, &id, properties).matches(PaintChunk(0, 1, &id, properties)));
|
||||
|
||||
// Delete the current object and create a new object at the same address.
|
||||
client = WTF::nullopt;
|
||||
client.emplace();
|
||||
EXPECT_TRUE(client->isJustCreated());
|
||||
EXPECT_FALSE(PaintChunk(0, 1, &id, properties).matches(PaintChunk(0, 1, &id, properties)));
|
||||
}
|
||||
|
||||
} // namespace blink
|
@ -16,41 +16,19 @@ PaintChunker::~PaintChunker()
|
||||
{
|
||||
}
|
||||
|
||||
void PaintChunker::updateCurrentPaintChunkProperties(const PaintChunk::Id* chunkId, const PaintChunkProperties& properties)
|
||||
void PaintChunker::updateCurrentPaintChunkProperties(const PaintChunkProperties& properties)
|
||||
{
|
||||
ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
|
||||
|
||||
m_currentChunkId = WTF::nullopt;
|
||||
if (chunkId)
|
||||
m_currentChunkId.emplace(*chunkId);
|
||||
m_currentProperties = properties;
|
||||
}
|
||||
|
||||
void PaintChunker::incrementDisplayItemIndex(const DisplayItem& item)
|
||||
void PaintChunker::incrementDisplayItemIndex(ItemBehavior behavior)
|
||||
{
|
||||
ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
|
||||
|
||||
ItemBehavior behavior;
|
||||
Optional<PaintChunk::Id> newChunkId;
|
||||
if (DisplayItem::isForeignLayerType(item.getType())) {
|
||||
behavior = RequiresSeparateChunk;
|
||||
// Use null chunkId if we are skipping cache, so that the chunk will not
|
||||
// match any old chunk and will be treated as brand new.
|
||||
if (!item.skippedCache())
|
||||
newChunkId.emplace(item.getId());
|
||||
|
||||
// Clear m_currentChunkId so that any display items after the foreign layer
|
||||
// without a new chunk id will be treated as having no id to avoid the chunk
|
||||
// from using the same id as the chunk before the foreign layer chunk.
|
||||
m_currentChunkId = WTF::nullopt;
|
||||
} else {
|
||||
behavior = DefaultBehavior;
|
||||
if (!item.skippedCache() && m_currentChunkId)
|
||||
newChunkId.emplace(*m_currentChunkId);
|
||||
}
|
||||
|
||||
if (m_chunks.isEmpty()) {
|
||||
PaintChunk newChunk(0, 1, newChunkId ? &*newChunkId : nullptr, m_currentProperties);
|
||||
PaintChunk newChunk(0, 1, m_currentProperties);
|
||||
m_chunks.append(newChunk);
|
||||
m_chunkBehavior.append(behavior);
|
||||
return;
|
||||
@ -65,7 +43,7 @@ void PaintChunker::incrementDisplayItemIndex(const DisplayItem& item)
|
||||
return;
|
||||
}
|
||||
|
||||
PaintChunk newChunk(lastChunk.endIndex, lastChunk.endIndex + 1, newChunkId ? &*newChunkId : nullptr, m_currentProperties);
|
||||
PaintChunk newChunk(lastChunk.endIndex, lastChunk.endIndex + 1, m_currentProperties);
|
||||
m_chunks.append(newChunk);
|
||||
m_chunkBehavior.append(behavior);
|
||||
}
|
||||
@ -88,7 +66,6 @@ void PaintChunker::clear()
|
||||
{
|
||||
m_chunks.clear();
|
||||
m_chunkBehavior.clear();
|
||||
m_currentChunkId = WTF::nullopt;
|
||||
m_currentProperties = PaintChunkProperties();
|
||||
}
|
||||
|
||||
@ -97,7 +74,6 @@ Vector<PaintChunk> PaintChunker::releasePaintChunks()
|
||||
Vector<PaintChunk> chunks;
|
||||
chunks.swap(m_chunks);
|
||||
m_chunkBehavior.clear();
|
||||
m_currentChunkId = WTF::nullopt;
|
||||
m_currentProperties = PaintChunkProperties();
|
||||
return chunks;
|
||||
}
|
||||
|
@ -6,7 +6,6 @@
|
||||
#define PaintChunker_h
|
||||
|
||||
#include "platform/PlatformExport.h"
|
||||
#include "platform/graphics/paint/DisplayItem.h"
|
||||
#include "platform/graphics/paint/PaintChunk.h"
|
||||
#include "platform/graphics/paint/PaintChunkProperties.h"
|
||||
#include "wtf/Allocator.h"
|
||||
@ -22,15 +21,23 @@ class PLATFORM_EXPORT PaintChunker final {
|
||||
DISALLOW_NEW();
|
||||
WTF_MAKE_NONCOPYABLE(PaintChunker);
|
||||
public:
|
||||
enum ItemBehavior {
|
||||
// Can be combined with adjacent items when building chunks.
|
||||
DefaultBehavior = 0,
|
||||
|
||||
// Item requires its own paint chunk.
|
||||
RequiresSeparateChunk,
|
||||
};
|
||||
|
||||
PaintChunker();
|
||||
~PaintChunker();
|
||||
|
||||
bool isInInitialState() const { return m_chunks.isEmpty() && m_currentProperties == PaintChunkProperties(); }
|
||||
|
||||
const PaintChunkProperties& currentPaintChunkProperties() const { return m_currentProperties; }
|
||||
void updateCurrentPaintChunkProperties(const PaintChunk::Id*, const PaintChunkProperties&);
|
||||
void updateCurrentPaintChunkProperties(const PaintChunkProperties&);
|
||||
|
||||
void incrementDisplayItemIndex(const DisplayItem&);
|
||||
void incrementDisplayItemIndex(ItemBehavior);
|
||||
void decrementDisplayItemIndex();
|
||||
|
||||
void clear();
|
||||
@ -40,17 +47,8 @@ public:
|
||||
Vector<PaintChunk> releasePaintChunks();
|
||||
|
||||
private:
|
||||
enum ItemBehavior {
|
||||
// Can be combined with adjacent items when building chunks.
|
||||
DefaultBehavior = 0,
|
||||
|
||||
// Item requires its own paint chunk.
|
||||
RequiresSeparateChunk,
|
||||
};
|
||||
|
||||
Vector<PaintChunk> m_chunks;
|
||||
Vector<ItemBehavior> m_chunkBehavior;
|
||||
Optional<PaintChunk::Id> m_currentChunkId;
|
||||
PaintChunkProperties m_currentProperties;
|
||||
};
|
||||
|
||||
|
@ -31,26 +31,6 @@ private:
|
||||
RuntimeEnabledFeatures::Backup m_featuresBackup;
|
||||
};
|
||||
|
||||
class TestDisplayItem : public DisplayItem, public DisplayItemClient {
|
||||
public:
|
||||
TestDisplayItem(DisplayItem::Type type) : DisplayItem(*this, type, sizeof(*this)) { }
|
||||
|
||||
void replay(GraphicsContext&) const final { NOTREACHED(); }
|
||||
void appendToWebDisplayItemList(const IntRect&, WebDisplayItemList*) const final { NOTREACHED(); }
|
||||
String debugName() const final { return "Test"; }
|
||||
LayoutRect visualRect() const final { return LayoutRect(); }
|
||||
};
|
||||
|
||||
class NormalTestDisplayItem : public TestDisplayItem {
|
||||
public:
|
||||
NormalTestDisplayItem() : TestDisplayItem(DisplayItem::DrawingFirst) { }
|
||||
};
|
||||
|
||||
class TestDisplayItemRequiringSeparateChunk : public TestDisplayItem {
|
||||
public:
|
||||
TestDisplayItemRequiringSeparateChunk() : TestDisplayItem(DisplayItem::ForeignLayerPlugin) { }
|
||||
};
|
||||
|
||||
TEST_F(PaintChunkerTest, Empty)
|
||||
{
|
||||
Vector<PaintChunk> chunks = PaintChunker().releasePaintChunks();
|
||||
@ -60,108 +40,108 @@ TEST_F(PaintChunkerTest, Empty)
|
||||
TEST_F(PaintChunkerTest, SingleNonEmptyRange)
|
||||
{
|
||||
PaintChunker chunker;
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
|
||||
|
||||
EXPECT_THAT(chunks, ElementsAre(
|
||||
PaintChunk(0, 2, nullptr, rootPaintChunkProperties())));
|
||||
PaintChunk(0, 2, rootPaintChunkProperties())));
|
||||
}
|
||||
|
||||
TEST_F(PaintChunkerTest, SamePropertiesTwiceCombineIntoOneChunk)
|
||||
{
|
||||
PaintChunker chunker;
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
|
||||
|
||||
EXPECT_THAT(chunks, ElementsAre(
|
||||
PaintChunk(0, 3, nullptr, rootPaintChunkProperties())));
|
||||
PaintChunk(0, 3, rootPaintChunkProperties())));
|
||||
}
|
||||
|
||||
TEST_F(PaintChunkerTest, CanRewindDisplayItemIndex)
|
||||
{
|
||||
PaintChunker chunker;
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.decrementDisplayItemIndex();
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
|
||||
|
||||
EXPECT_THAT(chunks, ElementsAre(
|
||||
PaintChunk(0, 2, nullptr, rootPaintChunkProperties())));
|
||||
PaintChunk(0, 2, rootPaintChunkProperties())));
|
||||
}
|
||||
|
||||
TEST_F(PaintChunkerTest, BuildMultipleChunksWithSinglePropertyChanging)
|
||||
{
|
||||
PaintChunker chunker;
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
|
||||
PaintChunkProperties simpleTransform;
|
||||
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
|
||||
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransform);
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(simpleTransform);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
|
||||
PaintChunkProperties anotherTransform;
|
||||
anotherTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, anotherTransform);
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(anotherTransform);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
|
||||
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
|
||||
|
||||
EXPECT_THAT(chunks, ElementsAre(
|
||||
PaintChunk(0, 2, nullptr, rootPaintChunkProperties()),
|
||||
PaintChunk(2, 3, nullptr, simpleTransform),
|
||||
PaintChunk(3, 4, nullptr, anotherTransform)));
|
||||
PaintChunk(0, 2, rootPaintChunkProperties()),
|
||||
PaintChunk(2, 3, simpleTransform),
|
||||
PaintChunk(3, 4, anotherTransform)));
|
||||
}
|
||||
|
||||
TEST_F(PaintChunkerTest, BuildMultipleChunksWithDifferentPropertyChanges)
|
||||
{
|
||||
PaintChunker chunker;
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
|
||||
PaintChunkProperties simpleTransform;
|
||||
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 0, 0, 0, 0, 0), FloatPoint3D(9, 8, 7));
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransform);
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(simpleTransform);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
|
||||
PaintChunkProperties simpleTransformAndEffect;
|
||||
simpleTransformAndEffect.transform = simpleTransform.transform;
|
||||
simpleTransformAndEffect.effect = EffectPaintPropertyNode::create(0.5f);
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransformAndEffect);
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(simpleTransformAndEffect);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
|
||||
PaintChunkProperties simpleTransformAndEffectWithUpdatedTransform;
|
||||
simpleTransformAndEffectWithUpdatedTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(1, 1, 0, 0, 0, 0), FloatPoint3D(9, 8, 7));
|
||||
simpleTransformAndEffectWithUpdatedTransform.effect = EffectPaintPropertyNode::create(simpleTransformAndEffect.effect->opacity());
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransformAndEffectWithUpdatedTransform);
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(simpleTransformAndEffectWithUpdatedTransform);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
|
||||
// Test that going back to a previous chunk property still creates a new chunk.
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransformAndEffect);
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(simpleTransformAndEffect);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
|
||||
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
|
||||
|
||||
EXPECT_THAT(chunks, ElementsAre(
|
||||
PaintChunk(0, 1, nullptr, rootPaintChunkProperties()),
|
||||
PaintChunk(1, 3, nullptr, simpleTransform),
|
||||
PaintChunk(3, 5, nullptr, simpleTransformAndEffect),
|
||||
PaintChunk(5, 7, nullptr, simpleTransformAndEffectWithUpdatedTransform),
|
||||
PaintChunk(7, 9, nullptr, simpleTransformAndEffect)));
|
||||
PaintChunk(0, 1, rootPaintChunkProperties()),
|
||||
PaintChunk(1, 3, simpleTransform),
|
||||
PaintChunk(3, 5, simpleTransformAndEffect),
|
||||
PaintChunk(5, 7, simpleTransformAndEffectWithUpdatedTransform),
|
||||
PaintChunk(7, 9, simpleTransformAndEffect)));
|
||||
}
|
||||
|
||||
TEST_F(PaintChunkerTest, BuildChunksFromNestedTransforms)
|
||||
@ -170,47 +150,47 @@ TEST_F(PaintChunkerTest, BuildChunksFromNestedTransforms)
|
||||
// sequence of transforms and display items:
|
||||
// <root xform>, <paint>, <a xform>, <paint>, <paint>, </a xform>, <paint>, </root xform>
|
||||
PaintChunker chunker;
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
|
||||
PaintChunkProperties simpleTransform;
|
||||
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransform);
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(simpleTransform);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
|
||||
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
|
||||
|
||||
EXPECT_THAT(chunks, ElementsAre(
|
||||
PaintChunk(0, 1, nullptr, rootPaintChunkProperties()),
|
||||
PaintChunk(1, 3, nullptr, simpleTransform),
|
||||
PaintChunk(3, 4, nullptr, rootPaintChunkProperties())));
|
||||
PaintChunk(0, 1, rootPaintChunkProperties()),
|
||||
PaintChunk(1, 3, simpleTransform),
|
||||
PaintChunk(3, 4, rootPaintChunkProperties())));
|
||||
}
|
||||
|
||||
TEST_F(PaintChunkerTest, ChangingPropertiesWithoutItems)
|
||||
{
|
||||
// Test that properties can change without display items being generated.
|
||||
PaintChunker chunker;
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
|
||||
PaintChunkProperties firstTransform;
|
||||
firstTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, firstTransform);
|
||||
chunker.updateCurrentPaintChunkProperties(firstTransform);
|
||||
|
||||
PaintChunkProperties secondTransform;
|
||||
secondTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(9, 8, 7, 6, 5, 4), FloatPoint3D(3, 2, 1));
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, secondTransform);
|
||||
chunker.updateCurrentPaintChunkProperties(secondTransform);
|
||||
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
|
||||
|
||||
EXPECT_THAT(chunks, ElementsAre(
|
||||
PaintChunk(0, 1, nullptr, rootPaintChunkProperties()),
|
||||
PaintChunk(1, 2, nullptr, secondTransform)));
|
||||
PaintChunk(0, 1, rootPaintChunkProperties()),
|
||||
PaintChunk(1, 2, secondTransform)));
|
||||
}
|
||||
|
||||
TEST_F(PaintChunkerTest, CreatesSeparateChunksWhenRequested)
|
||||
@ -218,99 +198,29 @@ TEST_F(PaintChunkerTest, CreatesSeparateChunksWhenRequested)
|
||||
// Tests that the chunker creates a separate chunks for display items which
|
||||
// require it.
|
||||
PaintChunker chunker;
|
||||
TestDisplayItemRequiringSeparateChunk i1, i2, i3, i4, i5, i6;
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(i1);
|
||||
chunker.incrementDisplayItemIndex(i2);
|
||||
chunker.incrementDisplayItemIndex(i3);
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(i4);
|
||||
chunker.incrementDisplayItemIndex(i5);
|
||||
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::RequiresSeparateChunk);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::RequiresSeparateChunk);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::RequiresSeparateChunk);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::RequiresSeparateChunk);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::RequiresSeparateChunk);
|
||||
chunker.decrementDisplayItemIndex();
|
||||
chunker.decrementDisplayItemIndex();
|
||||
chunker.decrementDisplayItemIndex();
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(i6);
|
||||
|
||||
DisplayItem::Id id1 = i1.getId();
|
||||
DisplayItem::Id id2 = i2.getId();
|
||||
DisplayItem::Id id3 = i3.getId();
|
||||
DisplayItem::Id id6 = i6.getId();
|
||||
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
|
||||
EXPECT_THAT(chunks, ElementsAre(
|
||||
PaintChunk(0, 1, nullptr, rootPaintChunkProperties()),
|
||||
PaintChunk(1, 2, &id1, rootPaintChunkProperties()),
|
||||
PaintChunk(2, 3, &id2, rootPaintChunkProperties()),
|
||||
PaintChunk(3, 4, &id3, rootPaintChunkProperties()),
|
||||
PaintChunk(4, 6, nullptr, rootPaintChunkProperties()),
|
||||
PaintChunk(6, 7, &id6, rootPaintChunkProperties())));
|
||||
}
|
||||
|
||||
TEST_F(PaintChunkerTest, ChunkIds)
|
||||
{
|
||||
PaintChunker chunker;
|
||||
TestDisplayItem i1(DisplayItem::DrawingFirst);
|
||||
DisplayItem::Id id1 = i1.getId();
|
||||
TestDisplayItemRequiringSeparateChunk i2;
|
||||
DisplayItem::Id id2 = i2.getId();
|
||||
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
|
||||
PaintChunkProperties simpleTransform;
|
||||
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
|
||||
chunker.updateCurrentPaintChunkProperties(&id1, simpleTransform);
|
||||
|
||||
chunker.incrementDisplayItemIndex(i1);
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(i2);
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
|
||||
chunker.incrementDisplayItemIndex(PaintChunker::RequiresSeparateChunk);
|
||||
|
||||
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
|
||||
EXPECT_THAT(chunks, ElementsAre(
|
||||
PaintChunk(0, 2, nullptr, rootPaintChunkProperties()),
|
||||
PaintChunk(2, 4, &id1, simpleTransform),
|
||||
PaintChunk(4, 5, &id2, simpleTransform),
|
||||
PaintChunk(5, 6, nullptr, simpleTransform),
|
||||
PaintChunk(6, 7, nullptr, rootPaintChunkProperties())));
|
||||
}
|
||||
|
||||
TEST_F(PaintChunkerTest, ChunkIdsSkippingCache)
|
||||
{
|
||||
PaintChunker chunker;
|
||||
TestDisplayItem i1(DisplayItem::DrawingFirst);
|
||||
i1.setSkippedCache();
|
||||
DisplayItem::Id id1 = i1.getId();
|
||||
TestDisplayItemRequiringSeparateChunk i2;
|
||||
i2.setSkippedCache();
|
||||
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
|
||||
PaintChunkProperties simpleTransform;
|
||||
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
|
||||
chunker.updateCurrentPaintChunkProperties(&id1, simpleTransform);
|
||||
|
||||
chunker.incrementDisplayItemIndex(i1);
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
chunker.incrementDisplayItemIndex(i2);
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
|
||||
chunker.updateCurrentPaintChunkProperties(nullptr, rootPaintChunkProperties());
|
||||
chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
|
||||
|
||||
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
|
||||
EXPECT_THAT(chunks, ElementsAre(
|
||||
PaintChunk(0, 2, nullptr, rootPaintChunkProperties()),
|
||||
PaintChunk(2, 4, nullptr, simpleTransform),
|
||||
PaintChunk(4, 5, nullptr, simpleTransform),
|
||||
PaintChunk(5, 6, nullptr, simpleTransform),
|
||||
PaintChunk(6, 7, nullptr, rootPaintChunkProperties())));
|
||||
PaintChunk(0, 1, rootPaintChunkProperties()),
|
||||
PaintChunk(1, 2, rootPaintChunkProperties()),
|
||||
PaintChunk(2, 3, rootPaintChunkProperties()),
|
||||
PaintChunk(3, 4, rootPaintChunkProperties()),
|
||||
PaintChunk(4, 6, rootPaintChunkProperties()),
|
||||
PaintChunk(6, 7, rootPaintChunkProperties())));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -17,6 +17,13 @@
|
||||
|
||||
namespace blink {
|
||||
|
||||
static PaintChunker::ItemBehavior behaviorOfItemType(DisplayItem::Type type)
|
||||
{
|
||||
if (DisplayItem::isForeignLayerType(type))
|
||||
return PaintChunker::RequiresSeparateChunk;
|
||||
return PaintChunker::DefaultBehavior;
|
||||
}
|
||||
|
||||
const PaintArtifact& PaintController::paintArtifact() const
|
||||
{
|
||||
DCHECK(m_newDisplayItemList.isEmpty());
|
||||
@ -158,7 +165,7 @@ void PaintController::processNewItem(DisplayItem& displayItem)
|
||||
DCHECK(!m_constructionDisabled);
|
||||
|
||||
#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
|
||||
if (!isSkippingCache()) {
|
||||
if (!skippingCache()) {
|
||||
if (displayItem.isCacheable()) {
|
||||
// Mark the client shouldKeepAlive under this PaintController.
|
||||
// The status will end after the new display items are committed.
|
||||
@ -189,7 +196,7 @@ void PaintController::processNewItem(DisplayItem& displayItem)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (isSkippingCache())
|
||||
if (skippingCache())
|
||||
displayItem.setSkippedCache();
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
@ -209,12 +216,12 @@ void PaintController::processNewItem(DisplayItem& displayItem)
|
||||
#endif // DCHECK_IS_ON()
|
||||
|
||||
if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
|
||||
m_newPaintChunks.incrementDisplayItemIndex(displayItem);
|
||||
m_newPaintChunks.incrementDisplayItemIndex(behaviorOfItemType(displayItem.getType()));
|
||||
}
|
||||
|
||||
void PaintController::updateCurrentPaintChunkProperties(const PaintChunk::Id* id, const PaintChunkProperties& newProperties)
|
||||
void PaintController::updateCurrentPaintChunkProperties(const PaintChunkProperties& newProperties)
|
||||
{
|
||||
m_newPaintChunks.updateCurrentPaintChunkProperties(id, newProperties);
|
||||
m_newPaintChunks.updateCurrentPaintChunkProperties(newProperties);
|
||||
}
|
||||
|
||||
const PaintChunkProperties& PaintController::currentPaintChunkProperties() const
|
||||
@ -235,7 +242,7 @@ bool PaintController::clientCacheIsValid(const DisplayItemClient& client) const
|
||||
#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
|
||||
CHECK(client.isAlive());
|
||||
#endif
|
||||
if (isSkippingCache())
|
||||
if (skippingCache())
|
||||
return false;
|
||||
return client.displayItemsAreCached(m_currentCacheGeneration);
|
||||
}
|
||||
@ -403,7 +410,7 @@ void PaintController::commitNewDisplayItems(const LayoutSize& offsetFromLayoutOb
|
||||
m_numCachedNewItems = 0;
|
||||
|
||||
// These data structures are used during painting only.
|
||||
DCHECK(!isSkippingCache());
|
||||
DCHECK(!skippingCache());
|
||||
#if DCHECK_IS_ON()
|
||||
m_newDisplayItemIndicesByClient.clear();
|
||||
#endif
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
|
||||
// Provide a new set of paint chunk properties to apply to recorded display
|
||||
// items, for Slimming Paint v2.
|
||||
void updateCurrentPaintChunkProperties(const PaintChunk::Id*, const PaintChunkProperties&);
|
||||
void updateCurrentPaintChunkProperties(const PaintChunkProperties&);
|
||||
|
||||
// Retrieve the current paint properties.
|
||||
const PaintChunkProperties& currentPaintChunkProperties() const;
|
||||
@ -111,7 +111,7 @@ public:
|
||||
|
||||
void beginSkippingCache() { ++m_skippingCacheCount; }
|
||||
void endSkippingCache() { DCHECK(m_skippingCacheCount > 0); --m_skippingCacheCount; }
|
||||
bool isSkippingCache() const { return m_skippingCacheCount; }
|
||||
bool skippingCache() const { return m_skippingCacheCount; }
|
||||
|
||||
// Must be called when a painting is finished.
|
||||
// offsetFromLayoutObject is the offset between the space of the GraphicsLayer which owns this
|
||||
|
@ -5,8 +5,6 @@
|
||||
#ifndef ScopedPaintChunkProperties_h
|
||||
#define ScopedPaintChunkProperties_h
|
||||
|
||||
#include "platform/graphics/paint/DisplayItem.h"
|
||||
#include "platform/graphics/paint/PaintChunk.h"
|
||||
#include "platform/graphics/paint/PaintChunkProperties.h"
|
||||
#include "platform/graphics/paint/PaintController.h"
|
||||
#include "wtf/Allocator.h"
|
||||
@ -18,27 +16,16 @@ class ScopedPaintChunkProperties {
|
||||
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
|
||||
WTF_MAKE_NONCOPYABLE(ScopedPaintChunkProperties);
|
||||
public:
|
||||
ScopedPaintChunkProperties(PaintController& paintController, const DisplayItemClient& client, DisplayItem::Type type, const PaintChunkProperties& properties)
|
||||
ScopedPaintChunkProperties(PaintController& paintController, const PaintChunkProperties& properties)
|
||||
: m_paintController(paintController)
|
||||
, m_previousProperties(paintController.currentPaintChunkProperties())
|
||||
{
|
||||
PaintChunk::Id id(client, type);
|
||||
m_paintController.updateCurrentPaintChunkProperties(&id, properties);
|
||||
m_paintController.updateCurrentPaintChunkProperties(properties);
|
||||
}
|
||||
|
||||
// Omits the type parameter, in case that the client creates only one PaintChunkProperties node during each painting.
|
||||
ScopedPaintChunkProperties(PaintController& paintController, const DisplayItemClient& client, const PaintChunkProperties& properties)
|
||||
: ScopedPaintChunkProperties(paintController, client, DisplayItem::UninitializedType, properties)
|
||||
{ }
|
||||
|
||||
~ScopedPaintChunkProperties()
|
||||
{
|
||||
// We should not return to the previous id, because that may cause a new chunk to use
|
||||
// the same id as that of the previous chunk before this ScopedPaintChunkProperties.
|
||||
// The painter should create another scope of paint properties with new id, or the
|
||||
// new chunk will have no id and will not match any old chunk and will be treated as
|
||||
// fully invalidated for rasterization.
|
||||
m_paintController.updateCurrentPaintChunkProperties(nullptr, m_previousProperties);
|
||||
m_paintController.updateCurrentPaintChunkProperties(m_previousProperties);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -20,12 +20,6 @@ public:
|
||||
String debugName() const final { return m_name; }
|
||||
LayoutRect visualRect() const override { return m_visualRect; }
|
||||
|
||||
// This simulates a paint without needing a PaintController.
|
||||
void updateCacheGeneration()
|
||||
{
|
||||
setDisplayItemsCached(CacheGenerationOrInvalidationReason::next());
|
||||
}
|
||||
|
||||
private:
|
||||
String m_name;
|
||||
LayoutRect m_visualRect;
|
||||
|
@ -45,19 +45,7 @@ void PrintTo(const PaintChunk& chunk, std::ostream* os)
|
||||
{
|
||||
*os << "PaintChunk(begin=" << chunk.beginIndex
|
||||
<< ", end=" << chunk.endIndex
|
||||
<< ", id=";
|
||||
if (!chunk.id) {
|
||||
*os << "null";
|
||||
} else {
|
||||
*os << "(" << &chunk.id->client << ", ";
|
||||
#ifndef NDEBUG
|
||||
*os << DisplayItem::typeAsDebugString(chunk.id->type);
|
||||
#else
|
||||
*os << static_cast<int>(chunk.id->type);
|
||||
#endif
|
||||
*os << ")";
|
||||
}
|
||||
*os << ", props=";
|
||||
<< ", props=";
|
||||
PrintTo(chunk.properties, os);
|
||||
*os << ", bounds=";
|
||||
PrintTo(chunk.bounds, os);
|
||||
|
Reference in New Issue
Block a user