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 |