Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "services/gfx/compositor/graph/scene_content.h" | |
| 6 | |
| 7 #include <ostream> | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "services/gfx/compositor/graph/scene_def.h" | |
| 11 | |
| 12 namespace compositor { | |
| 13 | |
| 14 SceneContent::SceneContent(const SceneLabel& label, | |
| 15 uint32_t version, | |
| 16 size_t max_resources, | |
| 17 size_t max_nodes) | |
| 18 : label_(label), | |
| 19 version_(version), | |
| 20 resources_(max_resources), | |
| 21 nodes_(max_nodes) {} | |
| 22 | |
| 23 SceneContent::~SceneContent() {} | |
| 24 | |
| 25 const ResourceDef* SceneContent::GetResource( | |
| 26 uint32_t resource_id, | |
| 27 ResourceDef::Type resource_type) const { | |
| 28 auto it = resources_.find(resource_id); | |
| 29 DCHECK(it != resources_.end()); | |
| 30 DCHECK(it->second->type() == resource_type); | |
| 31 return it->second.get(); | |
| 32 } | |
| 33 | |
| 34 const NodeDef* SceneContent::GetNode(uint32_t node_id) const { | |
| 35 auto it = nodes_.find(node_id); | |
| 36 DCHECK(it != nodes_.end()); | |
| 37 return it->second.get(); | |
| 38 } | |
| 39 | |
| 40 const NodeDef* SceneContent::GetRootNodeIfExists() const { | |
| 41 auto it = nodes_.find(mojo::gfx::composition::kSceneRootNodeId); | |
| 42 return it != nodes_.end() ? it->second.get() : nullptr; | |
| 43 } | |
| 44 | |
| 45 SceneContentBuilder::SceneContentBuilder(const SceneDef* scene, | |
| 46 uint32_t version, | |
| 47 std::ostream& err, | |
| 48 size_t max_resources, | |
| 49 size_t max_nodes) | |
| 50 : content_( | |
| 51 new SceneContent(scene->label(), version, max_resources, max_nodes)), | |
| 52 scene_(scene), | |
| 53 err_(err) { | |
| 54 DCHECK(scene); | |
| 55 } | |
| 56 | |
| 57 SceneContentBuilder::~SceneContentBuilder() {} | |
| 58 | |
| 59 const ResourceDef* SceneContentBuilder::RequireResource( | |
| 60 uint32_t resource_id, | |
| 61 ResourceDef::Type resource_type, | |
| 62 uint32_t referrer_node_id) { | |
| 63 DCHECK(content_); | |
| 64 | |
| 65 auto it = content_->resources_.find(resource_id); | |
| 66 if (it != content_->resources_.end()) | |
| 67 return it->second.get(); // found | |
|
abarth
2016/03/01 17:21:26
I'd skip this comment. It's a common pattern for
jeffbrown
2016/03/02 00:32:16
Done.
| |
| 68 | |
| 69 const ResourceDef* resource = scene_->FindResource(resource_id); | |
| 70 if (!resource) { | |
| 71 err_ << "Missing resource " << resource_id << " referenced from node " | |
| 72 << content_->FormattedLabelForNode(referrer_node_id); | |
| 73 return nullptr; | |
| 74 } | |
| 75 | |
| 76 if (resource->type() != resource_type) { | |
| 77 err_ << "Resource " << resource_id << " referenced from node " | |
| 78 << content_->FormattedLabelForNode(referrer_node_id) | |
| 79 << " has incorrect type for its intended usage"; | |
| 80 return nullptr; | |
| 81 } | |
| 82 | |
| 83 content_->resources_.emplace(std::make_pair(resource_id, resource)); | |
| 84 return resource; | |
| 85 } | |
| 86 | |
| 87 const NodeDef* SceneContentBuilder::RequireNode(uint32_t node_id, | |
| 88 uint32_t referrer_node_id) { | |
| 89 DCHECK(content_); | |
| 90 | |
| 91 auto it = content_->nodes_.find(node_id); | |
| 92 if (it != content_->nodes_.end()) { | |
| 93 if (it->second) | |
| 94 return it->second.get(); // already added | |
| 95 err_ << "Cycle detected at node " << node_id << " referenced from node " | |
| 96 << content_->FormattedLabelForNode(referrer_node_id); | |
| 97 return nullptr; | |
| 98 } | |
| 99 | |
| 100 const NodeDef* node = scene_->FindNode(node_id); | |
| 101 if (!node) { | |
| 102 err_ << "Missing node " << node_id << " referenced from node " | |
| 103 << content_->FormattedLabelForNode(referrer_node_id); | |
| 104 return nullptr; | |
| 105 } | |
| 106 | |
| 107 return AddNode(node) ? node : nullptr; | |
| 108 } | |
| 109 | |
| 110 bool SceneContentBuilder::AddNode(const NodeDef* node) { | |
| 111 DCHECK(content_); | |
| 112 DCHECK(node); | |
| 113 | |
| 114 // Reserve a spot in the table to mark the node recording in progress. | |
| 115 content_->nodes_.emplace(std::make_pair(node->node_id(), nullptr)); | |
| 116 | |
| 117 // Record the node's content. | |
| 118 // This performs a depth first search of the node. If it succeeds, we | |
| 119 // will know that this part of the graph has no cycles. | |
| 120 if (!node->RecordContent(this)) | |
| 121 return false; | |
| 122 | |
| 123 // Store the node in the table. | |
| 124 content_->nodes_[node->node_id()] = node; | |
|
abarth
2016/03/01 17:21:26
There's a pattern for doing this without doing two
jeffbrown
2016/03/02 00:32:16
You're correct that we can do this but the reasons
| |
| 125 return true; | |
| 126 } | |
| 127 | |
| 128 scoped_refptr<const SceneContent> SceneContentBuilder::Build() { | |
| 129 DCHECK(content_); | |
| 130 | |
| 131 const NodeDef* root = scene_->FindRootNode(); | |
| 132 return !root || AddNode(root) ? std::move(content_) : nullptr; | |
| 133 } | |
| 134 | |
| 135 } // namespace compositor | |
| OLD | NEW |