| 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 cfe2e254f150eeae2a97c53998492b9adb9346e4..99c1609120a32c2b2a7b711b553438f06b204e24 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/RasterInvalidationTracking.h"
|
| #include "platform/graphics/paint/ScrollPaintPropertyNode.h"
|
| #include "platform/graphics/paint/TransformPaintPropertyNode.h"
|
| #include "public/platform/Platform.h"
|
| @@ -46,14 +47,31 @@
|
|
|
| namespace blink {
|
|
|
| +template class RasterInvalidationTrackingMap<const cc::Layer>;
|
| +static RasterInvalidationTrackingMap<const cc::Layer>&
|
| +ccLayersRasterInvalidationTrackingMap() {
|
| + DEFINE_STATIC_LOCAL(RasterInvalidationTrackingMap<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)
|
| - : m_id(paintChunkId), m_ccPictureLayer(cc::PictureLayer::Create(this)) {}
|
| + ContentLayerClientImpl(DisplayItem::Id paintChunkId)
|
| + : m_id(paintChunkId),
|
| + m_debugName(paintChunkId.client.debugName()),
|
| + m_ccPictureLayer(cc::PictureLayer::Create(this)) {}
|
|
|
| void SetDisplayList(scoped_refptr<cc::DisplayItemList> ccDisplayItemList) {
|
| m_ccDisplayItemList = std::move(ccDisplayItemList);
|
| @@ -72,14 +90,70 @@ class PaintArtifactCompositor::ContentLayerClientImpl
|
| return 0;
|
| }
|
|
|
| + void resetTrackedRasterInvalidations() {
|
| + RasterInvalidationTracking* tracking =
|
| + ccLayersRasterInvalidationTrackingMap().find(m_ccPictureLayer.get());
|
| + if (!tracking)
|
| + return;
|
| +
|
| + if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled())
|
| + tracking->trackedRasterInvalidations.clear();
|
| + else
|
| + ccLayersRasterInvalidationTrackingMap().remove(m_ccPictureLayer.get());
|
| + }
|
| +
|
| + bool hasTrackedRasterInvalidations() const {
|
| + RasterInvalidationTracking* tracking =
|
| + ccLayersRasterInvalidationTrackingMap().find(m_ccPictureLayer.get());
|
| + if (tracking)
|
| + return !tracking->trackedRasterInvalidations.isEmpty();
|
| + return false;
|
| + }
|
| +
|
| + void setNeedsDisplayRect(const gfx::Rect& rect,
|
| + RasterInvalidationInfo* rasterInvalidationInfo) {
|
| + m_ccPictureLayer->SetNeedsDisplayRect(rect);
|
| +
|
| + if (!rasterInvalidationInfo || rect.IsEmpty())
|
| + return;
|
| +
|
| + RasterInvalidationTracking& tracking =
|
| + ccLayersRasterInvalidationTrackingMap().add(m_ccPictureLayer.get());
|
| +
|
| + tracking.trackedRasterInvalidations.append(*rasterInvalidationInfo);
|
| +
|
| + if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) {
|
| + // TODO(crbug.com/496260): Some antialiasing effects overflows the paint invalidation rect.
|
| + IntRect r = rasterInvalidationInfo->rect;
|
| + r.inflate(1);
|
| + tracking.rasterInvalidationRegionSinceLastPaint.unite(r);
|
| + }
|
| + }
|
| +
|
| + std::unique_ptr<JSONObject> layerAsJSON() {
|
| + std::unique_ptr<JSONObject> json = JSONObject::create();
|
| + json->setString("name", m_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());
|
| +
|
| + ccLayersRasterInvalidationTrackingMap().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;
|
| + String m_debugName;
|
| scoped_refptr<cc::PictureLayer> m_ccPictureLayer;
|
| scoped_refptr<cc::DisplayItemList> m_ccDisplayItemList;
|
| gfx::Rect m_paintableRegion;
|
| @@ -92,10 +166,41 @@ PaintArtifactCompositor::PaintArtifactCompositor() {
|
| m_webLayer = wrapUnique(
|
| Platform::current()->compositorSupport()->createLayerFromCCLayer(
|
| m_rootLayer.get()));
|
| + m_isTrackingRasterInvalidations = false;
|
| }
|
|
|
| PaintArtifactCompositor::~PaintArtifactCompositor() {}
|
|
|
| +void PaintArtifactCompositor::setTracksRasterInvalidations(
|
| + bool tracksPaintInvalidations) {
|
| + resetTrackedRasterInvalidations();
|
| + m_isTrackingRasterInvalidations = tracksPaintInvalidations;
|
| +}
|
| +
|
| +void PaintArtifactCompositor::resetTrackedRasterInvalidations() {
|
| + for (auto& client : m_contentLayerClients)
|
| + client->resetTrackedRasterInvalidations();
|
| +}
|
| +
|
| +bool PaintArtifactCompositor::hasTrackedRasterInvalidations() const {
|
| + for (auto& client : m_contentLayerClients) {
|
| + if (client->hasTrackedRasterInvalidations())
|
| + 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);
|
| @@ -213,21 +318,28 @@ void setMinimalPropertyTrees(cc::PropertyTrees* propertyTrees, int ownerId) {
|
| } // namespace
|
|
|
| std::unique_ptr<PaintArtifactCompositor::ContentLayerClientImpl>
|
| -PaintArtifactCompositor::clientForPaintChunk(const PaintChunk& paintChunk) {
|
| +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.
|
| for (auto& client : m_contentLayerClients) {
|
| 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,
|
| - Vector<std::unique_ptr<ContentLayerClientImpl>>& newContentLayerClients) {
|
| + Vector<std::unique_ptr<ContentLayerClientImpl>>& newContentLayerClients,
|
| + RasterInvalidationTracking* tracking) {
|
| DCHECK(paintChunk.size());
|
|
|
| // If the paint chunk is a foreign layer, just return that layer.
|
| @@ -237,7 +349,7 @@ scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(
|
|
|
| // The common case: create or reuse a PictureLayer for painted content.
|
| std::unique_ptr<ContentLayerClientImpl> contentLayerClient =
|
| - clientForPaintChunk(paintChunk);
|
| + clientForPaintChunk(paintChunk, paintArtifact);
|
|
|
| gfx::Rect combinedBounds = enclosingIntRect(paintChunk.bounds);
|
| scoped_refptr<cc::DisplayItemList> displayList =
|
| @@ -252,13 +364,19 @@ scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(
|
| ccPictureLayer->SetIsDrawable(true);
|
| if (paintChunk.knownToBeOpaque)
|
| ccPictureLayer->SetContentsOpaque(true);
|
| - for (auto& invalidation : paintChunk.rasterInvalidationRects) {
|
| - IntRect rect(enclosingIntRect(invalidation));
|
| + DCHECK(!tracking ||
|
| + tracking->trackedRasterInvalidations.size() ==
|
| + paintChunk.rasterInvalidationRects.size());
|
| + for (unsigned index = 0; index < paintChunk.rasterInvalidationRects.size();
|
| + ++index) {
|
| + IntRect rect(enclosingIntRect(paintChunk.rasterInvalidationRects[index]));
|
| gfx::Rect ccInvalidationRect(rect.x(), rect.y(), std::max(0, rect.width()),
|
| std::max(0, rect.height()));
|
| - // 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);
|
| + // Raster paintChunk.rasterInvalidationRects is in the space of the containing transform node, so need to subtract off the layer offset.
|
| + contentLayerClient->setNeedsDisplayRect(
|
| + ccInvalidationRect,
|
| + tracking ? &tracking->trackedRasterInvalidations[index] : nullptr);
|
| }
|
|
|
| newContentLayerClients.append(std::move(contentLayerClient));
|
| @@ -568,7 +686,9 @@ void PropertyTreeManager::buildEffectNodesRecursively(
|
|
|
| } // namespace
|
|
|
| -void PaintArtifactCompositor::update(const PaintArtifact& paintArtifact) {
|
| +void PaintArtifactCompositor::update(
|
| + const PaintArtifact& paintArtifact,
|
| + RasterInvalidationTrackingMap<const PaintChunk>* rasterChunkInvalidations) {
|
| DCHECK(m_rootLayer);
|
|
|
| cc::LayerTree* layerTree = m_rootLayer->GetLayerTree();
|
| @@ -599,7 +719,9 @@ void PaintArtifactCompositor::update(const PaintArtifact& paintArtifact) {
|
| for (const PaintChunk& paintChunk : paintArtifact.paintChunks()) {
|
| gfx::Vector2dF layerOffset;
|
| scoped_refptr<cc::Layer> layer = layerForPaintChunk(
|
| - paintArtifact, paintChunk, layerOffset, newContentLayerClients);
|
| + paintArtifact, paintChunk, layerOffset, newContentLayerClients,
|
| + rasterChunkInvalidations ? rasterChunkInvalidations->find(&paintChunk)
|
| + : nullptr);
|
|
|
| int transformId = propertyTreeManager.compositorIdForTransformNode(
|
| paintChunk.properties.transform.get());
|
|
|