| Index: third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
|
| diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
|
| index bebcf687f4b08fcffb69e03e828888d20c54acdb..d5d531ccfd55b6535f15299572dccb84bb67b05b 100644
|
| --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
|
| +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
|
| @@ -24,6 +24,7 @@
|
| #include "platform/graphics/paint/ForeignLayerDisplayItem.h"
|
| #include "platform/graphics/paint/GeometryPropertyTreeState.h"
|
| #include "platform/graphics/paint/PaintArtifact.h"
|
| +#include "platform/graphics/paint/PaintInvalidationTracking.h"
|
| #include "platform/graphics/paint/ScrollPaintPropertyNode.h"
|
| #include "platform/graphics/paint/TransformPaintPropertyNode.h"
|
| #include "public/platform/Platform.h"
|
| @@ -46,11 +47,27 @@
|
|
|
| namespace blink {
|
|
|
| +template class PaintInvalidationTrackingMap<const cc::Layer>;
|
| +static PaintInvalidationTrackingMap<const cc::Layer>& paintInvalidationTrackingMap()
|
| +{
|
| + DEFINE_STATIC_LOCAL(PaintInvalidationTrackingMap<const cc::Layer>, map, ());
|
| + return map;
|
| +}
|
| +
|
| +template <typename T>
|
| +static std::unique_ptr<JSONArray> sizeAsJSONArray(const T& size)
|
| +{
|
| + std::unique_ptr<JSONArray> array = JSONArray::create();
|
| + array->pushDouble(size.width());
|
| + array->pushDouble(size.height());
|
| + return array;
|
| +}
|
| +
|
| class PaintArtifactCompositor::ContentLayerClientImpl : public cc::ContentLayerClient {
|
| WTF_MAKE_NONCOPYABLE(ContentLayerClientImpl);
|
| USING_FAST_MALLOC(ContentLayerClientImpl);
|
| public:
|
| - ContentLayerClientImpl(Optional<DisplayItem::Id> paintChunkId)
|
| + ContentLayerClientImpl(DisplayItem::Id paintChunkId)
|
| : m_id(paintChunkId), m_ccPictureLayer(cc::PictureLayer::Create(this))
|
| {
|
| }
|
| @@ -71,15 +88,71 @@ public:
|
| return 0;
|
| }
|
|
|
| + void resetTrackedPaintInvalidations()
|
| + {
|
| + PaintInvalidationTracking* tracking = paintInvalidationTrackingMap().find(m_ccPictureLayer.get());
|
| + if (!tracking)
|
| + return;
|
| +
|
| + if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled())
|
| + tracking->trackedPaintInvalidations.clear();
|
| + else
|
| + paintInvalidationTrackingMap().remove(m_ccPictureLayer.get());
|
| + }
|
| +
|
| + bool hasTrackedPaintInvalidations() const
|
| + {
|
| + PaintInvalidationTracking* tracking = paintInvalidationTrackingMap().find(m_ccPictureLayer.get());
|
| + if (tracking)
|
| + return !tracking->trackedPaintInvalidations.isEmpty();
|
| + return false;
|
| + }
|
| +
|
| + void setNeedsDisplayRect(const PaintInvalidationInfo& invalidation, bool trackPaintInvalidation)
|
| + {
|
| + m_ccPictureLayer->SetNeedsDisplayRect(invalidation.rect);
|
| +
|
| + if (!RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled() && !trackPaintInvalidation)
|
| + return;
|
| + if (invalidation.rect.isEmpty())
|
| + return;
|
| +
|
| + PaintInvalidationTracking& tracking = paintInvalidationTrackingMap().add(m_ccPictureLayer.get());
|
| +
|
| + if (trackPaintInvalidation)
|
| + tracking.trackedPaintInvalidations.append(invalidation);
|
| +
|
| + if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) {
|
| + // TODO(crbug.com/496260): Some antialiasing effects overflows the paint invalidation rect.
|
| + IntRect r = invalidation.rect;
|
| + r.inflate(1);
|
| + tracking.paintInvalidationRegionSinceLastPaint.unite(r);
|
| + }
|
| + }
|
| +
|
| + std::unique_ptr<JSONObject> layerAsJSON()
|
| + {
|
| + std::unique_ptr<JSONObject> json = JSONObject::create();
|
| + json->setString("id", m_id.client.debugName());
|
| + IntSize bounds(m_ccPictureLayer->bounds().width(), m_ccPictureLayer->bounds().height());
|
| + if (!bounds.isEmpty())
|
| + json->setArray("bounds", sizeAsJSONArray(bounds));
|
| + json->setBoolean("contentsOpaque", m_ccPictureLayer->contents_opaque());
|
| + json->setBoolean("drawsContent", m_ccPictureLayer->DrawsContent());
|
| +
|
| + paintInvalidationTrackingMap().asJSON(m_ccPictureLayer.get(), json.get());
|
| + return json;
|
| + }
|
| +
|
| scoped_refptr<cc::PictureLayer> ccPictureLayer() { return m_ccPictureLayer; }
|
|
|
| bool matches(const PaintChunk& paintChunk)
|
| {
|
| - return m_id && paintChunk.id && *m_id == *paintChunk.id;
|
| + return paintChunk.id && m_id == *paintChunk.id;
|
| }
|
|
|
| private:
|
| - Optional<PaintChunk::Id> m_id;
|
| + PaintChunk::Id m_id;
|
| scoped_refptr<cc::PictureLayer> m_ccPictureLayer;
|
| scoped_refptr<cc::DisplayItemList> m_ccDisplayItemList;
|
| gfx::Rect m_paintableRegion;
|
| @@ -91,12 +164,46 @@ PaintArtifactCompositor::PaintArtifactCompositor()
|
| return;
|
| m_rootLayer = cc::Layer::Create();
|
| m_webLayer = wrapUnique(Platform::current()->compositorSupport()->createLayerFromCCLayer(m_rootLayer.get()));
|
| + m_isTrackingPaintInvalidations = false;
|
| }
|
|
|
| PaintArtifactCompositor::~PaintArtifactCompositor()
|
| {
|
| }
|
|
|
| +void PaintArtifactCompositor::setTracksPaintInvalidations(bool tracksPaintInvalidations)
|
| +{
|
| + resetTrackedPaintInvalidations();
|
| + m_isTrackingPaintInvalidations = tracksPaintInvalidations;
|
| +}
|
| +
|
| +void PaintArtifactCompositor::resetTrackedPaintInvalidations()
|
| +{
|
| + for (auto& client : m_contentLayerClients)
|
| + client->resetTrackedPaintInvalidations();
|
| +}
|
| +
|
| +bool PaintArtifactCompositor::hasTrackedPaintInvalidations() const
|
| +{
|
| + for (auto& client : m_contentLayerClients) {
|
| + if (client->hasTrackedPaintInvalidations())
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +std::unique_ptr<JSONObject> PaintArtifactCompositor::layersAsJSON(LayerTreeFlags flags) const
|
| +{
|
| + std::unique_ptr<JSONArray> layersJSON = JSONArray::create();
|
| + for (const auto& client : m_contentLayerClients) {
|
| + layersJSON->pushObject(client->layerAsJSON());
|
| + }
|
| +
|
| + std::unique_ptr<JSONObject> json = JSONObject::create();
|
| + json->setArray("layers", std::move(layersJSON));
|
| + return json;
|
| +}
|
| +
|
| namespace {
|
|
|
| static gfx::Rect largeRect(-200000, -200000, 400000, 400000);
|
| @@ -200,7 +307,7 @@ void setMinimalPropertyTrees(cc::PropertyTrees* propertyTrees, int ownerId)
|
|
|
| } // namespace
|
|
|
| -std::unique_ptr<PaintArtifactCompositor::ContentLayerClientImpl> PaintArtifactCompositor::clientForPaintChunk(const PaintChunk& paintChunk)
|
| +std::unique_ptr<PaintArtifactCompositor::ContentLayerClientImpl> PaintArtifactCompositor::clientForPaintChunk(const PaintChunk& paintChunk, const PaintArtifact& paintArtifact)
|
| {
|
| // TODO(chrishtr): for now, just using a linear walk. In the future we can optimize this by using the same techniques used in
|
| // PaintController for display lists.
|
| @@ -208,7 +315,8 @@ std::unique_ptr<PaintArtifactCompositor::ContentLayerClientImpl> PaintArtifactCo
|
| if (client && client->matches(paintChunk))
|
| return std::move(client);
|
| }
|
| - return wrapUnique(new ContentLayerClientImpl(paintChunk.id));
|
| +
|
| + return wrapUnique(new ContentLayerClientImpl(paintChunk.id ? *paintChunk.id : paintArtifact.getDisplayItemList()[paintChunk.beginIndex].getId()));
|
| }
|
|
|
| scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const PaintArtifact& paintArtifact, const PaintChunk& paintChunk, gfx::Vector2dF& layerOffset,
|
| @@ -221,7 +329,7 @@ scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const Paint
|
| return foreignLayer;
|
|
|
| // The common case: create or reuse a PictureLayer for painted content.
|
| - std::unique_ptr<ContentLayerClientImpl> contentLayerClient = clientForPaintChunk(paintChunk);
|
| + std::unique_ptr<ContentLayerClientImpl> contentLayerClient = clientForPaintChunk(paintChunk, paintArtifact);
|
|
|
| gfx::Rect combinedBounds = enclosingIntRect(paintChunk.bounds);
|
| scoped_refptr<cc::DisplayItemList> displayList = recordPaintChunk(paintArtifact, paintChunk, combinedBounds);
|
| @@ -234,12 +342,11 @@ scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const Paint
|
| ccPictureLayer->SetIsDrawable(true);
|
| if (paintChunk.knownToBeOpaque)
|
| ccPictureLayer->SetContentsOpaque(true);
|
| - for (auto& invalidation : paintChunk.rasterInvalidationRects) {
|
| - IntRect rect(enclosingIntRect(invalidation));
|
| - gfx::Rect ccInvalidationRect(rect.x(), rect.y(), std::max(0, rect.width()), std::max(0, rect.height()));
|
| + for (auto invalidation : paintChunk.rasterInvalidationRects) {
|
| + invalidation.rect = enclosingIntRect(invalidation.rect);
|
| + invalidation.rect.move(IntSize(-combinedBounds.x(), -combinedBounds.y()));
|
| // Raster paintChunk.rasterInvalidationRects is in the space of the containing transform node, so need to subtract off the layer offset.
|
| - ccInvalidationRect.Offset(-combinedBounds.OffsetFromOrigin());
|
| - ccPictureLayer->SetNeedsDisplayRect(ccInvalidationRect);
|
| + contentLayerClient->setNeedsDisplayRect(invalidation, m_isTrackingPaintInvalidations);
|
| }
|
|
|
| newContentLayerClients.append(std::move(contentLayerClient));
|
|
|