OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "platform/graphics/compositing/PaintArtifactCompositor.h" | 5 #include "platform/graphics/compositing/PaintArtifactCompositor.h" |
6 | 6 |
7 #include "cc/layers/content_layer_client.h" | 7 #include "cc/layers/content_layer_client.h" |
8 #include "cc/layers/layer.h" | 8 #include "cc/layers/layer.h" |
9 #include "cc/layers/picture_layer.h" | 9 #include "cc/layers/picture_layer.h" |
10 #include "cc/playback/display_item_list.h" | 10 #include "cc/playback/display_item_list.h" |
11 #include "cc/playback/display_item_list_settings.h" | 11 #include "cc/playback/display_item_list_settings.h" |
12 #include "cc/playback/drawing_display_item.h" | 12 #include "cc/playback/drawing_display_item.h" |
13 #include "cc/playback/transform_display_item.h" | 13 #include "cc/playback/transform_display_item.h" |
14 #include "cc/trees/clip_node.h" | 14 #include "cc/trees/clip_node.h" |
15 #include "cc/trees/effect_node.h" | 15 #include "cc/trees/effect_node.h" |
16 #include "cc/trees/layer_tree_host.h" | 16 #include "cc/trees/layer_tree_host.h" |
17 #include "cc/trees/property_tree.h" | 17 #include "cc/trees/property_tree.h" |
18 #include "cc/trees/scroll_node.h" | 18 #include "cc/trees/scroll_node.h" |
19 #include "cc/trees/transform_node.h" | 19 #include "cc/trees/transform_node.h" |
20 #include "platform/RuntimeEnabledFeatures.h" | 20 #include "platform/RuntimeEnabledFeatures.h" |
21 #include "platform/graphics/paint/ClipPaintPropertyNode.h" | 21 #include "platform/graphics/paint/ClipPaintPropertyNode.h" |
22 #include "platform/graphics/paint/DisplayItem.h" | 22 #include "platform/graphics/paint/DisplayItem.h" |
23 #include "platform/graphics/paint/DrawingDisplayItem.h" | 23 #include "platform/graphics/paint/DrawingDisplayItem.h" |
24 #include "platform/graphics/paint/ForeignLayerDisplayItem.h" | 24 #include "platform/graphics/paint/ForeignLayerDisplayItem.h" |
25 #include "platform/graphics/paint/GeometryPropertyTreeState.h" | 25 #include "platform/graphics/paint/GeometryPropertyTreeState.h" |
26 #include "platform/graphics/paint/PaintArtifact.h" | 26 #include "platform/graphics/paint/PaintArtifact.h" |
| 27 #include "platform/graphics/paint/PaintInvalidationTracking.h" |
27 #include "platform/graphics/paint/ScrollPaintPropertyNode.h" | 28 #include "platform/graphics/paint/ScrollPaintPropertyNode.h" |
28 #include "platform/graphics/paint/TransformPaintPropertyNode.h" | 29 #include "platform/graphics/paint/TransformPaintPropertyNode.h" |
29 #include "public/platform/Platform.h" | 30 #include "public/platform/Platform.h" |
30 #include "public/platform/WebCompositorSupport.h" | 31 #include "public/platform/WebCompositorSupport.h" |
31 #include "public/platform/WebLayer.h" | 32 #include "public/platform/WebLayer.h" |
32 #include "ui/gfx/geometry/point.h" | 33 #include "ui/gfx/geometry/point.h" |
33 #include "ui/gfx/geometry/point_f.h" | 34 #include "ui/gfx/geometry/point_f.h" |
34 #include "ui/gfx/geometry/rect.h" | 35 #include "ui/gfx/geometry/rect.h" |
35 #include "ui/gfx/geometry/rect_f.h" | 36 #include "ui/gfx/geometry/rect_f.h" |
36 #include "ui/gfx/geometry/size.h" | 37 #include "ui/gfx/geometry/size.h" |
37 #include "ui/gfx/geometry/size_conversions.h" | 38 #include "ui/gfx/geometry/size_conversions.h" |
38 #include "ui/gfx/geometry/size_f.h" | 39 #include "ui/gfx/geometry/size_f.h" |
39 #include "ui/gfx/skia_util.h" | 40 #include "ui/gfx/skia_util.h" |
40 #include "wtf/Allocator.h" | 41 #include "wtf/Allocator.h" |
41 #include "wtf/Noncopyable.h" | 42 #include "wtf/Noncopyable.h" |
42 #include "wtf/PtrUtil.h" | 43 #include "wtf/PtrUtil.h" |
43 #include <algorithm> | 44 #include <algorithm> |
44 #include <memory> | 45 #include <memory> |
45 #include <utility> | 46 #include <utility> |
46 | 47 |
47 namespace blink { | 48 namespace blink { |
48 | 49 |
| 50 template class PaintInvalidationTrackingMap<const cc::Layer>; |
| 51 static PaintInvalidationTrackingMap<const cc::Layer>& paintInvalidationTrackingM
ap() |
| 52 { |
| 53 DEFINE_STATIC_LOCAL(PaintInvalidationTrackingMap<const cc::Layer>, map, ()); |
| 54 return map; |
| 55 } |
| 56 |
| 57 template <typename T> |
| 58 static std::unique_ptr<JSONArray> sizeAsJSONArray(const T& size) |
| 59 { |
| 60 std::unique_ptr<JSONArray> array = JSONArray::create(); |
| 61 array->pushDouble(size.width()); |
| 62 array->pushDouble(size.height()); |
| 63 return array; |
| 64 } |
| 65 |
49 class PaintArtifactCompositor::ContentLayerClientImpl : public cc::ContentLayerC
lient { | 66 class PaintArtifactCompositor::ContentLayerClientImpl : public cc::ContentLayerC
lient { |
50 WTF_MAKE_NONCOPYABLE(ContentLayerClientImpl); | 67 WTF_MAKE_NONCOPYABLE(ContentLayerClientImpl); |
51 USING_FAST_MALLOC(ContentLayerClientImpl); | 68 USING_FAST_MALLOC(ContentLayerClientImpl); |
52 public: | 69 public: |
53 ContentLayerClientImpl(Optional<DisplayItem::Id> paintChunkId) | 70 ContentLayerClientImpl(DisplayItem::Id paintChunkId) |
54 : m_id(paintChunkId), m_ccPictureLayer(cc::PictureLayer::Create(this)) | 71 : m_id(paintChunkId), m_ccPictureLayer(cc::PictureLayer::Create(this)) |
55 { | 72 { |
56 } | 73 } |
57 | 74 |
58 void SetDisplayList(scoped_refptr<cc::DisplayItemList> ccDisplayItemList) {
m_ccDisplayItemList = std::move(ccDisplayItemList); } | 75 void SetDisplayList(scoped_refptr<cc::DisplayItemList> ccDisplayItemList) {
m_ccDisplayItemList = std::move(ccDisplayItemList); } |
59 void SetPaintableRegion(gfx::Rect region) { m_paintableRegion = region; } | 76 void SetPaintableRegion(gfx::Rect region) { m_paintableRegion = region; } |
60 | 77 |
61 // cc::ContentLayerClient | 78 // cc::ContentLayerClient |
62 gfx::Rect PaintableRegion() override { return m_paintableRegion; } | 79 gfx::Rect PaintableRegion() override { return m_paintableRegion; } |
63 scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList(PaintingContro
lSetting) override | 80 scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList(PaintingContro
lSetting) override |
64 { | 81 { |
65 return m_ccDisplayItemList; | 82 return m_ccDisplayItemList; |
66 } | 83 } |
67 bool FillsBoundsCompletely() const override { return false; } | 84 bool FillsBoundsCompletely() const override { return false; } |
68 size_t GetApproximateUnsharedMemoryUsage() const override | 85 size_t GetApproximateUnsharedMemoryUsage() const override |
69 { | 86 { |
70 // TODO(jbroman): Actually calculate memory usage. | 87 // TODO(jbroman): Actually calculate memory usage. |
71 return 0; | 88 return 0; |
72 } | 89 } |
73 | 90 |
| 91 void resetTrackedPaintInvalidations() |
| 92 { |
| 93 PaintInvalidationTracking* tracking = paintInvalidationTrackingMap().fin
d(m_ccPictureLayer.get()); |
| 94 if (!tracking) |
| 95 return; |
| 96 |
| 97 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) |
| 98 tracking->trackedPaintInvalidations.clear(); |
| 99 else |
| 100 paintInvalidationTrackingMap().remove(m_ccPictureLayer.get()); |
| 101 } |
| 102 |
| 103 bool hasTrackedPaintInvalidations() const |
| 104 { |
| 105 PaintInvalidationTracking* tracking = paintInvalidationTrackingMap().fin
d(m_ccPictureLayer.get()); |
| 106 if (tracking) |
| 107 return !tracking->trackedPaintInvalidations.isEmpty(); |
| 108 return false; |
| 109 } |
| 110 |
| 111 void setNeedsDisplayRect(const PaintInvalidationInfo& invalidation, bool tra
ckPaintInvalidation) |
| 112 { |
| 113 m_ccPictureLayer->SetNeedsDisplayRect(invalidation.rect); |
| 114 |
| 115 if (!RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled() &&
!trackPaintInvalidation) |
| 116 return; |
| 117 if (invalidation.rect.isEmpty()) |
| 118 return; |
| 119 |
| 120 PaintInvalidationTracking& tracking = paintInvalidationTrackingMap().add
(m_ccPictureLayer.get()); |
| 121 |
| 122 if (trackPaintInvalidation) |
| 123 tracking.trackedPaintInvalidations.append(invalidation); |
| 124 |
| 125 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) { |
| 126 // TODO(crbug.com/496260): Some antialiasing effects overflows the p
aint invalidation rect. |
| 127 IntRect r = invalidation.rect; |
| 128 r.inflate(1); |
| 129 tracking.paintInvalidationRegionSinceLastPaint.unite(r); |
| 130 } |
| 131 } |
| 132 |
| 133 std::unique_ptr<JSONObject> layerAsJSON() |
| 134 { |
| 135 std::unique_ptr<JSONObject> json = JSONObject::create(); |
| 136 json->setString("id", m_id.client.debugName()); |
| 137 IntSize bounds(m_ccPictureLayer->bounds().width(), m_ccPictureLayer->bou
nds().height()); |
| 138 if (!bounds.isEmpty()) |
| 139 json->setArray("bounds", sizeAsJSONArray(bounds)); |
| 140 json->setBoolean("contentsOpaque", m_ccPictureLayer->contents_opaque()); |
| 141 json->setBoolean("drawsContent", m_ccPictureLayer->DrawsContent()); |
| 142 |
| 143 paintInvalidationTrackingMap().asJSON(m_ccPictureLayer.get(), json.get()
); |
| 144 return json; |
| 145 } |
| 146 |
74 scoped_refptr<cc::PictureLayer> ccPictureLayer() { return m_ccPictureLayer;
} | 147 scoped_refptr<cc::PictureLayer> ccPictureLayer() { return m_ccPictureLayer;
} |
75 | 148 |
76 bool matches(const PaintChunk& paintChunk) | 149 bool matches(const PaintChunk& paintChunk) |
77 { | 150 { |
78 return m_id && paintChunk.id && *m_id == *paintChunk.id; | 151 return paintChunk.id && m_id == *paintChunk.id; |
79 } | 152 } |
80 | 153 |
81 private: | 154 private: |
82 Optional<PaintChunk::Id> m_id; | 155 PaintChunk::Id m_id; |
83 scoped_refptr<cc::PictureLayer> m_ccPictureLayer; | 156 scoped_refptr<cc::PictureLayer> m_ccPictureLayer; |
84 scoped_refptr<cc::DisplayItemList> m_ccDisplayItemList; | 157 scoped_refptr<cc::DisplayItemList> m_ccDisplayItemList; |
85 gfx::Rect m_paintableRegion; | 158 gfx::Rect m_paintableRegion; |
86 }; | 159 }; |
87 | 160 |
88 PaintArtifactCompositor::PaintArtifactCompositor() | 161 PaintArtifactCompositor::PaintArtifactCompositor() |
89 { | 162 { |
90 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 163 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
91 return; | 164 return; |
92 m_rootLayer = cc::Layer::Create(); | 165 m_rootLayer = cc::Layer::Create(); |
93 m_webLayer = wrapUnique(Platform::current()->compositorSupport()->createLaye
rFromCCLayer(m_rootLayer.get())); | 166 m_webLayer = wrapUnique(Platform::current()->compositorSupport()->createLaye
rFromCCLayer(m_rootLayer.get())); |
| 167 m_isTrackingPaintInvalidations = false; |
94 } | 168 } |
95 | 169 |
96 PaintArtifactCompositor::~PaintArtifactCompositor() | 170 PaintArtifactCompositor::~PaintArtifactCompositor() |
97 { | 171 { |
98 } | 172 } |
99 | 173 |
| 174 void PaintArtifactCompositor::setTracksPaintInvalidations(bool tracksPaintInvali
dations) |
| 175 { |
| 176 resetTrackedPaintInvalidations(); |
| 177 m_isTrackingPaintInvalidations = tracksPaintInvalidations; |
| 178 } |
| 179 |
| 180 void PaintArtifactCompositor::resetTrackedPaintInvalidations() |
| 181 { |
| 182 for (auto& client : m_contentLayerClients) |
| 183 client->resetTrackedPaintInvalidations(); |
| 184 } |
| 185 |
| 186 bool PaintArtifactCompositor::hasTrackedPaintInvalidations() const |
| 187 { |
| 188 for (auto& client : m_contentLayerClients) { |
| 189 if (client->hasTrackedPaintInvalidations()) |
| 190 return true; |
| 191 } |
| 192 return false; |
| 193 } |
| 194 |
| 195 std::unique_ptr<JSONObject> PaintArtifactCompositor::layersAsJSON(LayerTreeFlags
flags) const |
| 196 { |
| 197 std::unique_ptr<JSONArray> layersJSON = JSONArray::create(); |
| 198 for (const auto& client : m_contentLayerClients) { |
| 199 layersJSON->pushObject(client->layerAsJSON()); |
| 200 } |
| 201 |
| 202 std::unique_ptr<JSONObject> json = JSONObject::create(); |
| 203 json->setArray("layers", std::move(layersJSON)); |
| 204 return json; |
| 205 } |
| 206 |
100 namespace { | 207 namespace { |
101 | 208 |
102 static gfx::Rect largeRect(-200000, -200000, 400000, 400000); | 209 static gfx::Rect largeRect(-200000, -200000, 400000, 400000); |
103 | 210 |
104 static void appendDisplayItemToCcDisplayItemList(const DisplayItem& displayItem,
cc::DisplayItemList* list) | 211 static void appendDisplayItemToCcDisplayItemList(const DisplayItem& displayItem,
cc::DisplayItemList* list) |
105 { | 212 { |
106 if (DisplayItem::isDrawingType(displayItem.getType())) { | 213 if (DisplayItem::isDrawingType(displayItem.getType())) { |
107 const SkPicture* picture = static_cast<const DrawingDisplayItem&>(displa
yItem).picture(); | 214 const SkPicture* picture = static_cast<const DrawingDisplayItem&>(displa
yItem).picture(); |
108 if (!picture) | 215 if (!picture) |
109 return; | 216 return; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 cc::ScrollTree& scrollTree = propertyTrees->scroll_tree; | 300 cc::ScrollTree& scrollTree = propertyTrees->scroll_tree; |
194 scrollTree.clear(); | 301 scrollTree.clear(); |
195 cc::ScrollNode& scrollNode = *scrollTree.Node(scrollTree.Insert(cc::ScrollNo
de(), kRealRootNodeId)); | 302 cc::ScrollNode& scrollNode = *scrollTree.Node(scrollTree.Insert(cc::ScrollNo
de(), kRealRootNodeId)); |
196 DCHECK_EQ(scrollNode.id, kSecondaryRootNodeId); | 303 DCHECK_EQ(scrollNode.id, kSecondaryRootNodeId); |
197 scrollNode.owner_id = ownerId; | 304 scrollNode.owner_id = ownerId; |
198 scrollNode.transform_id = kRealRootNodeId; | 305 scrollNode.transform_id = kRealRootNodeId; |
199 } | 306 } |
200 | 307 |
201 } // namespace | 308 } // namespace |
202 | 309 |
203 std::unique_ptr<PaintArtifactCompositor::ContentLayerClientImpl> PaintArtifactCo
mpositor::clientForPaintChunk(const PaintChunk& paintChunk) | 310 std::unique_ptr<PaintArtifactCompositor::ContentLayerClientImpl> PaintArtifactCo
mpositor::clientForPaintChunk(const PaintChunk& paintChunk, const PaintArtifact&
paintArtifact) |
204 { | 311 { |
205 // TODO(chrishtr): for now, just using a linear walk. In the future we can o
ptimize this by using the same techniques used in | 312 // TODO(chrishtr): for now, just using a linear walk. In the future we can o
ptimize this by using the same techniques used in |
206 // PaintController for display lists. | 313 // PaintController for display lists. |
207 for (auto& client : m_contentLayerClients) { | 314 for (auto& client : m_contentLayerClients) { |
208 if (client && client->matches(paintChunk)) | 315 if (client && client->matches(paintChunk)) |
209 return std::move(client); | 316 return std::move(client); |
210 } | 317 } |
211 return wrapUnique(new ContentLayerClientImpl(paintChunk.id)); | 318 |
| 319 return wrapUnique(new ContentLayerClientImpl(paintChunk.id ? *paintChunk.id
: paintArtifact.getDisplayItemList()[paintChunk.beginIndex].getId())); |
212 } | 320 } |
213 | 321 |
214 scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const Paint
Artifact& paintArtifact, const PaintChunk& paintChunk, gfx::Vector2dF& layerOffs
et, | 322 scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const Paint
Artifact& paintArtifact, const PaintChunk& paintChunk, gfx::Vector2dF& layerOffs
et, |
215 Vector<std::unique_ptr<ContentLayerClientImpl>>& newContentLayerClients) | 323 Vector<std::unique_ptr<ContentLayerClientImpl>>& newContentLayerClients) |
216 { | 324 { |
217 DCHECK(paintChunk.size()); | 325 DCHECK(paintChunk.size()); |
218 | 326 |
219 // If the paint chunk is a foreign layer, just return that layer. | 327 // If the paint chunk is a foreign layer, just return that layer. |
220 if (scoped_refptr<cc::Layer> foreignLayer = foreignLayerForPaintChunk(paintA
rtifact, paintChunk, layerOffset)) | 328 if (scoped_refptr<cc::Layer> foreignLayer = foreignLayerForPaintChunk(paintA
rtifact, paintChunk, layerOffset)) |
221 return foreignLayer; | 329 return foreignLayer; |
222 | 330 |
223 // The common case: create or reuse a PictureLayer for painted content. | 331 // The common case: create or reuse a PictureLayer for painted content. |
224 std::unique_ptr<ContentLayerClientImpl> contentLayerClient = clientForPaintC
hunk(paintChunk); | 332 std::unique_ptr<ContentLayerClientImpl> contentLayerClient = clientForPaintC
hunk(paintChunk, paintArtifact); |
225 | 333 |
226 gfx::Rect combinedBounds = enclosingIntRect(paintChunk.bounds); | 334 gfx::Rect combinedBounds = enclosingIntRect(paintChunk.bounds); |
227 scoped_refptr<cc::DisplayItemList> displayList = recordPaintChunk(paintArtif
act, paintChunk, combinedBounds); | 335 scoped_refptr<cc::DisplayItemList> displayList = recordPaintChunk(paintArtif
act, paintChunk, combinedBounds); |
228 contentLayerClient->SetDisplayList(std::move(displayList)); | 336 contentLayerClient->SetDisplayList(std::move(displayList)); |
229 contentLayerClient->SetPaintableRegion(gfx::Rect(combinedBounds.size())); | 337 contentLayerClient->SetPaintableRegion(gfx::Rect(combinedBounds.size())); |
230 | 338 |
231 layerOffset = combinedBounds.OffsetFromOrigin(); | 339 layerOffset = combinedBounds.OffsetFromOrigin(); |
232 scoped_refptr<cc::PictureLayer> ccPictureLayer = contentLayerClient->ccPictu
reLayer(); | 340 scoped_refptr<cc::PictureLayer> ccPictureLayer = contentLayerClient->ccPictu
reLayer(); |
233 ccPictureLayer->SetBounds(combinedBounds.size()); | 341 ccPictureLayer->SetBounds(combinedBounds.size()); |
234 ccPictureLayer->SetIsDrawable(true); | 342 ccPictureLayer->SetIsDrawable(true); |
235 if (paintChunk.knownToBeOpaque) | 343 if (paintChunk.knownToBeOpaque) |
236 ccPictureLayer->SetContentsOpaque(true); | 344 ccPictureLayer->SetContentsOpaque(true); |
237 for (auto& invalidation : paintChunk.rasterInvalidationRects) { | 345 for (auto invalidation : paintChunk.rasterInvalidationRects) { |
238 IntRect rect(enclosingIntRect(invalidation)); | 346 invalidation.rect = enclosingIntRect(invalidation.rect); |
239 gfx::Rect ccInvalidationRect(rect.x(), rect.y(), std::max(0, rect.width(
)), std::max(0, rect.height())); | 347 invalidation.rect.move(IntSize(-combinedBounds.x(), -combinedBounds.y())
); |
240 // Raster paintChunk.rasterInvalidationRects is in the space of the cont
aining transform node, so need to subtract off the layer offset. | 348 // Raster paintChunk.rasterInvalidationRects is in the space of the cont
aining transform node, so need to subtract off the layer offset. |
241 ccInvalidationRect.Offset(-combinedBounds.OffsetFromOrigin()); | 349 contentLayerClient->setNeedsDisplayRect(invalidation, m_isTrackingPaintI
nvalidations); |
242 ccPictureLayer->SetNeedsDisplayRect(ccInvalidationRect); | |
243 } | 350 } |
244 | 351 |
245 newContentLayerClients.append(std::move(contentLayerClient)); | 352 newContentLayerClients.append(std::move(contentLayerClient)); |
246 return ccPictureLayer; | 353 return ccPictureLayer; |
247 } | 354 } |
248 | 355 |
249 namespace { | 356 namespace { |
250 | 357 |
251 class PropertyTreeManager { | 358 class PropertyTreeManager { |
252 WTF_MAKE_NONCOPYABLE(PropertyTreeManager); | 359 WTF_MAKE_NONCOPYABLE(PropertyTreeManager); |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 } | 692 } |
586 m_contentLayerClients.clear(); | 693 m_contentLayerClients.clear(); |
587 m_contentLayerClients.swap(newContentLayerClients); | 694 m_contentLayerClients.swap(newContentLayerClients); |
588 | 695 |
589 // Mark the property trees as having been rebuilt. | 696 // Mark the property trees as having been rebuilt. |
590 layerTree->property_trees()->sequence_number = kPropertyTreeSequenceNumber; | 697 layerTree->property_trees()->sequence_number = kPropertyTreeSequenceNumber; |
591 layerTree->property_trees()->needs_rebuild = false; | 698 layerTree->property_trees()->needs_rebuild = false; |
592 } | 699 } |
593 | 700 |
594 } // namespace blink | 701 } // namespace blink |
OLD | NEW |