Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(734)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp

Issue 2101683002: [SPv2] Begin to convert the Blink transform tree to cc. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: I can haz unit test Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/layer_tree_host.h" 14 #include "cc/trees/layer_tree_host.h"
15 #include "cc/trees/property_tree.h"
15 #include "platform/RuntimeEnabledFeatures.h" 16 #include "platform/RuntimeEnabledFeatures.h"
16 #include "platform/graphics/paint/ClipPaintPropertyNode.h" 17 #include "platform/graphics/paint/ClipPaintPropertyNode.h"
17 #include "platform/graphics/paint/DisplayItem.h" 18 #include "platform/graphics/paint/DisplayItem.h"
18 #include "platform/graphics/paint/DrawingDisplayItem.h" 19 #include "platform/graphics/paint/DrawingDisplayItem.h"
19 #include "platform/graphics/paint/ForeignLayerDisplayItem.h" 20 #include "platform/graphics/paint/ForeignLayerDisplayItem.h"
20 #include "platform/graphics/paint/PaintArtifact.h" 21 #include "platform/graphics/paint/PaintArtifact.h"
21 #include "platform/graphics/paint/TransformPaintPropertyNode.h" 22 #include "platform/graphics/paint/TransformPaintPropertyNode.h"
22 #include "public/platform/Platform.h" 23 #include "public/platform/Platform.h"
23 #include "public/platform/WebCompositorSupport.h" 24 #include "public/platform/WebCompositorSupport.h"
24 #include "public/platform/WebLayer.h" 25 #include "public/platform/WebLayer.h"
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 static const int kSecondaryRootNodeId = 1; 263 static const int kSecondaryRootNodeId = 1;
263 static const int kPropertyTreeSequenceNumber = 1; 264 static const int kPropertyTreeSequenceNumber = 1;
264 265
265 // Creates a minimal set of property trees for the compositor. 266 // Creates a minimal set of property trees for the compositor.
266 void setMinimalPropertyTrees(cc::PropertyTrees* propertyTrees, int ownerId) 267 void setMinimalPropertyTrees(cc::PropertyTrees* propertyTrees, int ownerId)
267 { 268 {
268 // cc's property trees expect a child of the actual root to be used. So we 269 // cc's property trees expect a child of the actual root to be used. So we
269 // need to create and populate an additional node for each type of tree. 270 // need to create and populate an additional node for each type of tree.
270 271
271 cc::TransformTree& transformTree = propertyTrees->transform_tree; 272 cc::TransformTree& transformTree = propertyTrees->transform_tree;
272 if (transformTree.size() < 2) { 273 transformTree.clear();
273 transformTree.Insert(cc::TransformNode(), kRealRootNodeId); 274 transformTree.Insert(cc::TransformNode(), kRealRootNodeId);
274 cc::TransformNode& transformNode = *transformTree.back(); 275 cc::TransformNode& transformNode = *transformTree.back();
275 transformTree.SetTargetId(transformNode.id, kRealRootNodeId); 276 transformTree.SetTargetId(transformNode.id, kRealRootNodeId);
276 transformTree.SetContentTargetId(transformNode.id, kSecondaryRootNodeId) ; 277 transformTree.SetContentTargetId(transformNode.id, kSecondaryRootNodeId);
277 transformNode.data.source_node_id = kRealRootNodeId; 278 transformNode.data.source_node_id = kRealRootNodeId;
278 transformNode.data.needs_local_transform_update = true; 279 transformNode.data.needs_local_transform_update = true;
279 transformNode.owner_id = ownerId; 280 transformNode.owner_id = ownerId;
280 transformTree.set_needs_update(true); 281 transformTree.set_needs_update(true);
281 }
282 DCHECK_EQ(transformTree.size(), 2u);
283 282
284 cc::ClipTree& clipTree = propertyTrees->clip_tree; 283 cc::ClipTree& clipTree = propertyTrees->clip_tree;
285 if (clipTree.size() < 2) { 284 clipTree.clear();
286 clipTree.Insert(cc::ClipNode(), kRealRootNodeId); 285 clipTree.Insert(cc::ClipNode(), kRealRootNodeId);
287 cc::ClipNode& clipNode = *clipTree.back(); 286 cc::ClipNode& clipNode = *clipTree.back();
288 clipNode.data.transform_id = kSecondaryRootNodeId; 287 clipNode.data.transform_id = kSecondaryRootNodeId;
289 clipNode.data.target_id = kSecondaryRootNodeId; 288 clipNode.data.target_id = kSecondaryRootNodeId;
290 clipNode.owner_id = ownerId; 289 clipNode.owner_id = ownerId;
291 clipTree.set_needs_update(true); 290 clipTree.set_needs_update(true);
292 }
293 DCHECK_EQ(clipTree.size(), 2u);
294 291
295 cc::EffectTree& effectTree = propertyTrees->effect_tree; 292 cc::EffectTree& effectTree = propertyTrees->effect_tree;
296 if (effectTree.size() < 2) { 293 effectTree.clear();
297 // This matches what cc does right now: the secondary root isn't a child 294 // This matches what cc does right now: the secondary root isn't a child
298 // of the first root (at index 0). This may not have been intentional. 295 // of the first root (at index 0). This may not have been intentional.
299 effectTree.Insert(cc::EffectNode(), kInvalidNodeId); 296 effectTree.Insert(cc::EffectNode(), kInvalidNodeId);
300 cc::EffectNode& effectNode = *effectTree.back(); 297 cc::EffectNode& effectNode = *effectTree.back();
301 effectNode.data.has_render_surface = true; 298 effectNode.data.has_render_surface = true;
302 effectNode.data.transform_id = kRealRootNodeId; 299 effectNode.data.transform_id = kRealRootNodeId;
303 effectNode.data.clip_id = kRealRootNodeId; 300 effectNode.data.clip_id = kRealRootNodeId;
304 effectNode.owner_id = ownerId; 301 effectNode.owner_id = ownerId;
305 effectTree.set_needs_update(true); 302 effectTree.set_needs_update(true);
306 }
307 DCHECK_EQ(effectTree.size(), 2u);
308 303
309 cc::ScrollTree& scrollTree = propertyTrees->scroll_tree; 304 cc::ScrollTree& scrollTree = propertyTrees->scroll_tree;
310 if (scrollTree.size() < 2) { 305 scrollTree.clear();
311 scrollTree.Insert(cc::ScrollNode(), kRealRootNodeId); 306 scrollTree.Insert(cc::ScrollNode(), kRealRootNodeId);
312 cc::ScrollNode& scrollNode = *scrollTree.back(); 307 cc::ScrollNode& scrollNode = *scrollTree.back();
313 scrollNode.data.scrollable = false; 308 scrollNode.data.scrollable = false;
314 scrollNode.data.transform_id = kSecondaryRootNodeId; 309 scrollNode.data.transform_id = kSecondaryRootNodeId;
315 scrollNode.owner_id = ownerId; 310 scrollNode.owner_id = ownerId;
316 scrollTree.set_needs_update(true); 311 scrollTree.set_needs_update(true);
317 }
318 DCHECK_EQ(scrollTree.size(), 2u);
319 } 312 }
320 313
321 } // namespace 314 } // namespace
322 315
323 void PaintArtifactCompositor::update(const PaintArtifact& paintArtifact) 316 void PaintArtifactCompositor::update(const PaintArtifact& paintArtifact)
324 { 317 {
325 DCHECK(m_rootLayer); 318 DCHECK(m_rootLayer);
326 319
320 if (m_extraDataForTestingEnabled)
321 m_extraDataForTesting = wrapUnique(new ExtraDataForTesting);
322
327 // If the compositor is configured to expect using flat layer lists plus 323 // If the compositor is configured to expect using flat layer lists plus
328 // property trees, then we should provide that format. 324 // property trees, then we should provide that format.
329 cc::LayerTreeHost* host = m_rootLayer->layer_tree_host(); 325 cc::LayerTreeHost* host = m_rootLayer->layer_tree_host();
330 const bool useLayerLists = host && host->settings().use_layer_lists; 326 const bool useLayerLists = host && host->settings().use_layer_lists;
331 if (useLayerLists) { 327 if (useLayerLists) {
332 updateInLayerListMode(paintArtifact); 328 updateInLayerListMode(paintArtifact);
333 return; 329 return;
334 } 330 }
335 331
336 // TODO(jbroman): This should be incremental. 332 // TODO(jbroman): This should be incremental.
(...skipping 16 matching lines...) Expand all
353 if (const auto* clip = paintChunk.properties.clip.get()) { 349 if (const auto* clip = paintChunk.properties.clip.get()) {
354 FloatPoint offsetDueToClipOffset = clip->clipRect().rect().location( ); 350 FloatPoint offsetDueToClipOffset = clip->clipRect().rect().location( );
355 gfx::Transform undoClipOffset; 351 gfx::Transform undoClipOffset;
356 undoClipOffset.Translate(-offsetDueToClipOffset.x(), -offsetDueToCli pOffset.y()); 352 undoClipOffset.Translate(-offsetDueToClipOffset.x(), -offsetDueToCli pOffset.y());
357 transform.ConcatTransform(undoClipOffset); 353 transform.ConcatTransform(undoClipOffset);
358 } 354 }
359 layer->SetTransform(transform); 355 layer->SetTransform(transform);
360 layer->SetDoubleSided(!paintChunk.properties.backfaceHidden); 356 layer->SetDoubleSided(!paintChunk.properties.backfaceHidden);
361 layer->SetNeedsDisplay(); 357 layer->SetNeedsDisplay();
362 parent->AddChild(layer); 358 parent->AddChild(layer);
359
360 if (m_extraDataForTestingEnabled)
361 m_extraDataForTesting->contentLayers.append(layer);
363 } 362 }
364 } 363 }
365 364
366 scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const Paint Artifact& paintArtifact, const PaintChunk& paintChunk, gfx::Vector2dF& layerOffs et) 365 scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const Paint Artifact& paintArtifact, const PaintChunk& paintChunk, gfx::Vector2dF& layerOffs et)
367 { 366 {
368 DCHECK(paintChunk.size()); 367 DCHECK(paintChunk.size());
369 368
370 // If the paint chunk is a foreign layer, just return that layer. 369 // If the paint chunk is a foreign layer, just return that layer.
371 if (scoped_refptr<cc::Layer> foreignLayer = foreignLayerForPaintChunk(paintA rtifact, paintChunk, layerOffset)) 370 if (scoped_refptr<cc::Layer> foreignLayer = foreignLayerForPaintChunk(paintA rtifact, paintChunk, layerOffset))
372 return foreignLayer; 371 return foreignLayer;
373 372
374 // The common case: create a layer for painted content. 373 // The common case: create a layer for painted content.
375 gfx::Rect combinedBounds = enclosingIntRect(paintChunk.bounds); 374 gfx::Rect combinedBounds = enclosingIntRect(paintChunk.bounds);
376 scoped_refptr<cc::DisplayItemList> displayList = recordPaintChunk(paintArtif act, paintChunk, combinedBounds); 375 scoped_refptr<cc::DisplayItemList> displayList = recordPaintChunk(paintArtif act, paintChunk, combinedBounds);
377 std::unique_ptr<ContentLayerClientImpl> contentLayerClient = wrapUnique( 376 std::unique_ptr<ContentLayerClientImpl> contentLayerClient = wrapUnique(
378 new ContentLayerClientImpl(std::move(displayList), gfx::Rect(combinedBou nds.size()))); 377 new ContentLayerClientImpl(std::move(displayList), gfx::Rect(combinedBou nds.size())));
379 378
380 layerOffset = combinedBounds.OffsetFromOrigin(); 379 layerOffset = combinedBounds.OffsetFromOrigin();
381 scoped_refptr<cc::PictureLayer> layer = cc::PictureLayer::Create(contentLaye rClient.get()); 380 scoped_refptr<cc::PictureLayer> layer = cc::PictureLayer::Create(contentLaye rClient.get());
382 layer->SetBounds(combinedBounds.size()); 381 layer->SetBounds(combinedBounds.size());
383 layer->SetIsDrawable(true); 382 layer->SetIsDrawable(true);
384 if (paintChunk.knownToBeOpaque) 383 if (paintChunk.knownToBeOpaque)
385 layer->SetContentsOpaque(true); 384 layer->SetContentsOpaque(true);
386 m_contentLayerClients.append(std::move(contentLayerClient)); 385 m_contentLayerClients.append(std::move(contentLayerClient));
387 return layer; 386 return layer;
388 } 387 }
389 388
389 namespace {
390
391 class TransformTreeManager {
392 WTF_MAKE_NONCOPYABLE(TransformTreeManager);
393 public:
394 TransformTreeManager(cc::TransformTree& transformTree, cc::Layer* dummyTrans formParent)
395 : m_transformTree(transformTree)
396 , m_dummyTransformParent(dummyTransformParent) {}
397
398 int compositorIdForNode(const TransformPaintPropertyNode*);
399
400 private:
401 // Transform tree which should be updated by the manager.
402 cc::TransformTree& m_transformTree;
403
404 // Layer to which transform "owner" layers should be added. These will not
405 // have any actual children, but at present must exist in the tree.
406 cc::Layer* m_dummyTransformParent;
trchen 2016/06/27 21:39:19 This made me thought it's some internal state to c
jbroman 2016/06/27 21:53:58 OK, done. It doesn't have to be the root (we could
407
408 // Map from Blink-side transform nodes to cc transform node indices.
409 HashMap<const TransformPaintPropertyNode*, int> m_nodeMap;
410 };
411
412 int TransformTreeManager::compositorIdForNode(const TransformPaintPropertyNode* transformNode)
413 {
414 if (!transformNode)
415 return kSecondaryRootNodeId;
416
417 auto it = m_nodeMap.find(transformNode);
418 if (it != m_nodeMap.end())
419 return it->value;
420
421 scoped_refptr<cc::Layer> dummyLayer = cc::Layer::Create();
422 int parentId = compositorIdForNode(transformNode->parent());
423 int id = m_transformTree.Insert(cc::TransformNode(), parentId);
424
425 cc::TransformNode& compositorNode = *m_transformTree.Node(id);
426 m_transformTree.SetTargetId(id, kSecondaryRootNodeId);
427 m_transformTree.SetContentTargetId(id, kSecondaryRootNodeId);
428 compositorNode.owner_id = dummyLayer->id();
429 compositorNode.data.source_node_id = parentId;
430 compositorNode.data.needs_local_transform_update = true;
431
432 FloatPoint3D origin = transformNode->origin();
433 compositorNode.data.pre_local.matrix().setTranslate(
434 -origin.x(), -origin.y(), -origin.z());
435 compositorNode.data.local.matrix() = TransformationMatrix::toSkMatrix44(tran sformNode->matrix());
436 compositorNode.data.post_local.matrix().setTranslate(
437 origin.x(), origin.y(), origin.z());
438 compositorNode.data.needs_local_transform_update = true;
439
440 m_dummyTransformParent->AddChild(dummyLayer);
441 dummyLayer->SetTransformTreeIndex(id);
442 dummyLayer->SetClipTreeIndex(kSecondaryRootNodeId);
443 dummyLayer->SetEffectTreeIndex(kSecondaryRootNodeId);
444 dummyLayer->SetScrollTreeIndex(kSecondaryRootNodeId);
445 dummyLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber);
446
447 auto result = m_nodeMap.set(transformNode, id);
448 DCHECK(result.isNewEntry);
449 m_transformTree.set_needs_update(true);
450 return id;
451 }
452
453 } // namespace
454
390 void PaintArtifactCompositor::updateInLayerListMode(const PaintArtifact& paintAr tifact) 455 void PaintArtifactCompositor::updateInLayerListMode(const PaintArtifact& paintAr tifact)
391 { 456 {
392 cc::LayerTreeHost* host = m_rootLayer->layer_tree_host(); 457 cc::LayerTreeHost* host = m_rootLayer->layer_tree_host();
393 458
394 // The root layer must be the owner so that the render surface 459 // The root layer must be the owner so that the render surface
395 // validation works. It's expected to own at least the effect node. 460 // validation works. It's expected to own at least the effect node.
396 setMinimalPropertyTrees(host->property_trees(), m_rootLayer->id()); 461 setMinimalPropertyTrees(host->property_trees(), m_rootLayer->id());
397 m_rootLayer->RemoveAllChildren(); 462 m_rootLayer->RemoveAllChildren();
398 m_rootLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); 463 m_rootLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber);
399 m_rootLayer->SetTransformTreeIndex(kSecondaryRootNodeId); 464 m_rootLayer->SetTransformTreeIndex(kSecondaryRootNodeId);
400 m_rootLayer->SetClipTreeIndex(kSecondaryRootNodeId); 465 m_rootLayer->SetClipTreeIndex(kSecondaryRootNodeId);
401 m_rootLayer->SetEffectTreeIndex(kSecondaryRootNodeId); 466 m_rootLayer->SetEffectTreeIndex(kSecondaryRootNodeId);
402 m_rootLayer->SetScrollTreeIndex(kSecondaryRootNodeId); 467 m_rootLayer->SetScrollTreeIndex(kSecondaryRootNodeId);
403 468
469 TransformTreeManager transformTreeManager(host->property_trees()->transform_ tree, m_rootLayer.get());
404 m_contentLayerClients.clear(); 470 m_contentLayerClients.clear();
405 m_contentLayerClients.reserveCapacity(paintArtifact.paintChunks().size()); 471 m_contentLayerClients.reserveCapacity(paintArtifact.paintChunks().size());
406 for (const PaintChunk& paintChunk : paintArtifact.paintChunks()) { 472 for (const PaintChunk& paintChunk : paintArtifact.paintChunks()) {
407 gfx::Vector2dF layerOffset; 473 gfx::Vector2dF layerOffset;
408 scoped_refptr<cc::Layer> layer = layerForPaintChunk(paintArtifact, paint Chunk, layerOffset); 474 scoped_refptr<cc::Layer> layer = layerForPaintChunk(paintArtifact, paint Chunk, layerOffset);
409 // This is only good enough to get trivial 2D translations working. 475
410 // We'll need to actually create more cc transform nodes to do any 476 int transformId = transformTreeManager.compositorIdForNode(paintChunk.pr operties.transform.get());
411 // more; then we'll express offset-to-transform-parent relative to 477 layer->set_offset_to_transform_parent(layerOffset);
412 // that transform node.
413 // TODO(jbroman): ^ Do that.
414 layer->set_offset_to_transform_parent(
415 transformToTransformSpace(paintChunk.properties.transform.get(), nul lptr).To2dTranslation()
416 + layerOffset);
417 478
418 m_rootLayer->AddChild(layer); 479 m_rootLayer->AddChild(layer);
419 layer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); 480 layer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber);
420 layer->SetTransformTreeIndex(kSecondaryRootNodeId); 481 layer->SetTransformTreeIndex(transformId);
421 layer->SetClipTreeIndex(kSecondaryRootNodeId); 482 layer->SetClipTreeIndex(kSecondaryRootNodeId);
422 layer->SetEffectTreeIndex(kSecondaryRootNodeId); 483 layer->SetEffectTreeIndex(kSecondaryRootNodeId);
423 layer->SetScrollTreeIndex(kSecondaryRootNodeId); 484 layer->SetScrollTreeIndex(kSecondaryRootNodeId);
485
486 if (m_extraDataForTestingEnabled)
487 m_extraDataForTesting->contentLayers.append(layer);
424 } 488 }
425 489
426 // Mark the property trees as having been rebuilt. 490 // Mark the property trees as having been rebuilt.
427 host->property_trees()->sequence_number = kPropertyTreeSequenceNumber; 491 host->property_trees()->sequence_number = kPropertyTreeSequenceNumber;
428 host->property_trees()->needs_rebuild = false; 492 host->property_trees()->needs_rebuild = false;
429 } 493 }
430 494
431 } // namespace blink 495 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698