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 "services/gfx/compositor/graph/scene_def.h" | 5 #include "services/gfx/compositor/graph/scene_def.h" |
6 | 6 |
7 #include <ostream> | 7 #include <ostream> |
8 #include <utility> | |
9 | 8 |
10 #include "base/bind.h" | 9 #include "base/bind.h" |
11 #include "base/logging.h" | 10 #include "base/logging.h" |
12 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
13 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
14 #include "mojo/services/gfx/composition/cpp/formatting.h" | 13 #include "mojo/services/gfx/composition/cpp/formatting.h" |
15 #include "services/gfx/compositor/graph/snapshot.h" | 14 #include "services/gfx/compositor/graph/scene_content.h" |
16 #include "services/gfx/compositor/render/render_image.h" | 15 #include "services/gfx/compositor/render/render_image.h" |
17 #include "services/gfx/compositor/render/render_layer.h" | |
18 | 16 |
19 namespace compositor { | 17 namespace compositor { |
20 | 18 |
21 namespace { | 19 namespace { |
22 // TODO(jeffbrown): Determine and document a more appropriate size limit | 20 // TODO(jeffbrown): Determine and document a more appropriate size limit |
23 // for transferred images as part of the image pipe abstraction instead. | 21 // for transferred images as part of the image pipe abstraction instead. |
24 const int32_t kMaxTextureWidth = 65536; | 22 const int32_t kMaxTextureWidth = 65536; |
25 const int32_t kMaxTextureHeight = 65536; | 23 const int32_t kMaxTextureHeight = 65536; |
26 | 24 |
27 void ReleaseMailboxTexture( | 25 void ReleaseMailboxTexture( |
28 mojo::gfx::composition::MailboxTextureCallbackPtr callback) { | 26 mojo::gfx::composition::MailboxTextureCallbackPtr callback) { |
29 if (callback) | 27 if (callback) |
30 callback->OnMailboxTextureReleased(); | 28 callback->OnMailboxTextureReleased(); |
31 } | 29 } |
32 } // namespace | 30 } // namespace |
33 | 31 |
34 SceneDef::SceneDef(mojo::gfx::composition::SceneTokenPtr scene_token, | 32 SceneDef::SceneDef(const SceneLabel& label) |
35 const std::string& label) | 33 : label_(label), weak_factory_(this) {} |
36 : scene_token_(scene_token.Pass()), label_(label) { | |
37 DCHECK(scene_token_); | |
38 } | |
39 | 34 |
40 SceneDef::~SceneDef() {} | 35 SceneDef::~SceneDef() {} |
41 | 36 |
42 void SceneDef::EnqueueUpdate(mojo::gfx::composition::SceneUpdatePtr update) { | 37 void SceneDef::EnqueueUpdate(mojo::gfx::composition::SceneUpdatePtr update) { |
43 DCHECK(update); | 38 DCHECK(update); |
44 pending_updates_.push_back(update.Pass()); | 39 pending_updates_.push_back(update.Pass()); |
45 } | 40 } |
46 | 41 |
47 void SceneDef::EnqueuePublish( | 42 void SceneDef::EnqueuePublish( |
48 mojo::gfx::composition::SceneMetadataPtr metadata) { | 43 mojo::gfx::composition::SceneMetadataPtr metadata) { |
(...skipping 12 matching lines...) Expand all Loading... |
61 // presentation time. | 56 // presentation time. |
62 size_t end = pending_publications_.size(); | 57 size_t end = pending_publications_.size(); |
63 for (;;) { | 58 for (;;) { |
64 if (!end) | 59 if (!end) |
65 return Disposition::kUnchanged; | 60 return Disposition::kUnchanged; |
66 if (pending_publications_[end - 1]->is_due(presentation_time)) | 61 if (pending_publications_[end - 1]->is_due(presentation_time)) |
67 break; // found last presentable publication | 62 break; // found last presentable publication |
68 end--; | 63 end--; |
69 } | 64 } |
70 | 65 |
71 // Prepare to apply all publications up to this point. | 66 // Apply all updates sequentially up to this point. |
72 uint32_t version = pending_publications_[end - 1]->metadata->version; | 67 version_ = pending_publications_[end - 1]->metadata->version; |
73 if (version_ != version) { | |
74 version_ = version; | |
75 formatted_label_cache_.clear(); | |
76 } | |
77 Invalidate(); | |
78 | |
79 // Apply all updates sequentially. | |
80 for (size_t index = 0; index < end; ++index) { | 68 for (size_t index = 0; index < end; ++index) { |
81 for (auto& update : pending_publications_[index]->updates) { | 69 for (auto& update : pending_publications_[index]->updates) { |
82 if (!ApplyUpdate(update.Pass(), resolver, unavailable_sender, err)) | 70 if (!ApplyUpdate(update.Pass(), resolver, unavailable_sender, err)) |
83 return Disposition::kFailed; | 71 return Disposition::kFailed; |
84 } | 72 } |
85 } | 73 } |
86 | 74 |
87 // Dequeue the publications we processed. | 75 // Dequeue the publications we processed. |
88 pending_publications_.erase(pending_publications_.begin(), | 76 pending_publications_.erase(pending_publications_.begin(), |
89 pending_publications_.begin() + end); | 77 pending_publications_.begin() + end); |
90 | 78 |
91 // Ensure the scene is in a valid state. | 79 // Rebuild the scene content, gathering all reachable nodes and resources |
92 if (!Validate(err)) | 80 // and verifying that everything is correctly linked. |
93 return Disposition::kFailed; | 81 SceneContentBuilder builder(this, version_, err, resources_.size(), |
94 return Disposition::kSucceeded; | 82 nodes_.size()); |
| 83 content_ = builder.Build(); |
| 84 return content_ ? Disposition::kSucceeded : Disposition::kFailed; |
95 } | 85 } |
96 | 86 |
97 bool SceneDef::ApplyUpdate(mojo::gfx::composition::SceneUpdatePtr update, | 87 bool SceneDef::ApplyUpdate(mojo::gfx::composition::SceneUpdatePtr update, |
98 const SceneResolver& resolver, | 88 const SceneResolver& resolver, |
99 const SceneUnavailableSender& unavailable_sender, | 89 const SceneUnavailableSender& unavailable_sender, |
100 std::ostream& err) { | 90 std::ostream& err) { |
101 DCHECK(update); | 91 DCHECK(update); |
102 | 92 |
| 93 // TODO(jeffbrown): We may be able to reuse some content from previous |
| 94 // versions even when the client removes and recreates resources or nodes. |
| 95 // To reduce unnecessary churn, consider keeping track of items which have |
| 96 // been removed or are being replaced then checking to see whether they |
| 97 // really changed. |
| 98 |
103 // Update resources. | 99 // Update resources. |
104 if (update->clear_resources) { | 100 if (update->clear_resources) { |
105 resources_.clear(); | 101 resources_.clear(); |
106 } | 102 } |
107 for (auto it = update->resources.begin(); it != update->resources.end(); | 103 for (auto it = update->resources.begin(); it != update->resources.end(); |
108 ++it) { | 104 ++it) { |
109 uint32_t resource_id = it.GetKey(); | 105 uint32_t resource_id = it.GetKey(); |
110 mojo::gfx::composition::ResourcePtr& resource_decl = it.GetValue(); | 106 mojo::gfx::composition::ResourcePtr& resource_decl = it.GetValue(); |
111 if (resource_decl) { | 107 if (resource_decl) { |
112 ResourceDef* resource = CreateResource(resource_id, resource_decl.Pass(), | 108 scoped_refptr<const ResourceDef> resource = CreateResource( |
113 resolver, unavailable_sender, err); | 109 resource_id, resource_decl.Pass(), resolver, unavailable_sender, err); |
114 if (!resource) | 110 if (!resource) |
115 return false; | 111 return false; |
116 resources_[resource_id].reset(resource); | 112 resources_[resource_id] = std::move(resource); |
117 } else { | 113 } else { |
118 resources_.erase(resource_id); | 114 resources_.erase(resource_id); |
119 } | 115 } |
120 } | 116 } |
121 | 117 |
122 // Update nodes. | 118 // Update nodes. |
123 if (update->clear_nodes) { | 119 if (update->clear_nodes) { |
124 nodes_.clear(); | 120 nodes_.clear(); |
125 } | 121 } |
126 for (auto it = update->nodes.begin(); it != update->nodes.end(); ++it) { | 122 for (auto it = update->nodes.begin(); it != update->nodes.end(); ++it) { |
127 uint32_t node_id = it.GetKey(); | 123 uint32_t node_id = it.GetKey(); |
128 mojo::gfx::composition::NodePtr& node_decl = it.GetValue(); | 124 mojo::gfx::composition::NodePtr& node_decl = it.GetValue(); |
129 if (node_decl) { | 125 if (node_decl) { |
130 NodeDef* node = CreateNode(node_id, node_decl.Pass(), err); | 126 scoped_refptr<const NodeDef> node = |
| 127 CreateNode(node_id, node_decl.Pass(), err); |
131 if (!node) | 128 if (!node) |
132 return false; | 129 return false; |
133 nodes_[node_id].reset(node); | 130 nodes_[node_id] = std::move(node); |
134 } else { | 131 } else { |
135 nodes_.erase(node_id); | 132 nodes_.erase(node_id); |
136 } | 133 } |
137 } | 134 } |
138 return true; | 135 return true; |
139 } | 136 } |
140 | 137 |
141 bool SceneDef::Validate(std::ostream& err) { | |
142 // Validate all nodes. | |
143 // TODO(jeffbrown): Figure out how to do this incrementally if it gets | |
144 // too expensive to process all nodes each time. | |
145 root_node_ = nullptr; | |
146 for (auto& pair : nodes_) { | |
147 uint32_t node_id = pair.first; | |
148 NodeDef* node = pair.second.get(); | |
149 if (!node->Validate(this, err)) | |
150 return false; | |
151 if (node_id == mojo::gfx::composition::kSceneRootNodeId) | |
152 root_node_ = node; | |
153 } | |
154 return true; | |
155 } | |
156 | |
157 bool SceneDef::UnlinkReferencedScene( | 138 bool SceneDef::UnlinkReferencedScene( |
158 SceneDef* scene, | 139 SceneDef* scene, |
159 const SceneUnavailableSender& unavailable_sender) { | 140 const SceneUnavailableSender& unavailable_sender) { |
160 DCHECK(scene); | 141 DCHECK(scene); |
161 | 142 |
162 bool changed = false; | 143 bool changed = false; |
163 for (auto& pair : resources_) { | 144 for (auto& pair : resources_) { |
164 if (pair.second->type() == ResourceDef::Type::kScene) { | 145 if (pair.second->type() == ResourceDef::Type::kScene) { |
165 auto scene_resource = static_cast<SceneResourceDef*>(pair.second.get()); | 146 auto scene_resource = |
166 if (scene_resource->referenced_scene() == scene) { | 147 static_cast<const SceneResourceDef*>(pair.second.get()); |
167 scene_resource->clear_referenced_scene(); | 148 if (scene_resource->referenced_scene().get() == scene) { |
168 Invalidate(); | |
169 changed = true; | 149 changed = true; |
| 150 pair.second = scene_resource->Unlink(); |
170 unavailable_sender.Run(pair.first); | 151 unavailable_sender.Run(pair.first); |
171 } | 152 } |
172 } | 153 } |
173 } | 154 } |
174 return changed; | 155 return changed; |
175 } | 156 } |
176 | 157 |
177 bool SceneDef::Snapshot(SnapshotBuilder* snapshot_builder, | 158 scoped_refptr<const ResourceDef> SceneDef::CreateResource( |
178 RenderLayerBuilder* layer_builder) { | |
179 DCHECK(snapshot_builder); | |
180 DCHECK(layer_builder); | |
181 | |
182 // Detect cycles. | |
183 if (visited_) { | |
184 if (snapshot_builder->block_log()) { | |
185 *snapshot_builder->block_log() | |
186 << "Scene blocked due to recursive cycle: " << FormattedLabel() | |
187 << std::endl; | |
188 } | |
189 return false; | |
190 } | |
191 | |
192 // Snapshot the contents of the scene. | |
193 visited_ = true; | |
194 bool success = SnapshotInner(snapshot_builder, layer_builder); | |
195 visited_ = false; | |
196 return success; | |
197 } | |
198 | |
199 bool SceneDef::SnapshotInner(SnapshotBuilder* snapshot_builder, | |
200 RenderLayerBuilder* layer_builder) { | |
201 // Note the dependency even if blocked. | |
202 snapshot_builder->AddSceneDependency(this); | |
203 | |
204 // Ensure we have a root node. | |
205 if (!root_node_) { | |
206 if (snapshot_builder->block_log()) { | |
207 *snapshot_builder->block_log() | |
208 << "Scene blocked due because it has no root node: " | |
209 << FormattedLabel() << std::endl; | |
210 } | |
211 return false; | |
212 } | |
213 | |
214 // Snapshot and draw the layer. | |
215 std::shared_ptr<RenderLayer> scene_layer = SnapshotLayer(snapshot_builder); | |
216 if (!scene_layer) | |
217 return false; | |
218 layer_builder->DrawLayer(scene_layer); | |
219 return true; | |
220 } | |
221 | |
222 std::shared_ptr<RenderLayer> SceneDef::SnapshotLayer( | |
223 SnapshotBuilder* snapshot_builder) { | |
224 if (cached_layer_) | |
225 return cached_layer_; | |
226 | |
227 RenderLayerBuilder scene_layer_builder; | |
228 scene_layer_builder.PushScene(scene_token_->value, version_); | |
229 if (!root_node_->Snapshot(snapshot_builder, &scene_layer_builder, this)) | |
230 return nullptr; | |
231 scene_layer_builder.PopScene(); | |
232 | |
233 // TODO(jeffbrown): Implement caching even when the scene has dependencies. | |
234 // There are some subtleties to be dealt with to ensure that caches | |
235 // are properly invalidated and that we don't accidentally cache layers which | |
236 // bake in decisions which counteract the intended cycle detection and | |
237 // avoidance behavior. Basically just need better bookkeeping. | |
238 std::shared_ptr<RenderLayer> scene_layer = scene_layer_builder.Build(); | |
239 if (!HasSceneResources()) | |
240 cached_layer_ = scene_layer; | |
241 return scene_layer; | |
242 } | |
243 | |
244 void SceneDef::Invalidate() { | |
245 cached_layer_.reset(); | |
246 } | |
247 | |
248 bool SceneDef::HasSceneResources() { | |
249 for (auto& pair : resources_) { | |
250 if (pair.second->type() == ResourceDef::Type::kScene) | |
251 return true; | |
252 } | |
253 return false; | |
254 } | |
255 | |
256 ResourceDef* SceneDef::CreateResource( | |
257 uint32_t resource_id, | 159 uint32_t resource_id, |
258 mojo::gfx::composition::ResourcePtr resource_decl, | 160 mojo::gfx::composition::ResourcePtr resource_decl, |
259 const SceneResolver& resolver, | 161 const SceneResolver& resolver, |
260 const SceneUnavailableSender& unavailable_sender, | 162 const SceneUnavailableSender& unavailable_sender, |
261 std::ostream& err) { | 163 std::ostream& err) { |
262 DCHECK(resource_decl); | 164 DCHECK(resource_decl); |
263 | 165 |
264 if (resource_decl->is_scene()) { | 166 if (resource_decl->is_scene()) { |
265 auto& scene_resource_decl = resource_decl->get_scene(); | 167 auto& scene_resource_decl = resource_decl->get_scene(); |
266 DCHECK(scene_resource_decl->scene_token); | 168 DCHECK(scene_resource_decl->scene_token); |
267 SceneDef* referenced_scene = | 169 |
268 resolver.Run(scene_resource_decl->scene_token.get()); | 170 const mojo::gfx::composition::SceneToken& scene_token = |
269 if (!referenced_scene) { | 171 *scene_resource_decl->scene_token; |
| 172 base::WeakPtr<SceneDef> referenced_scene = resolver.Run(scene_token); |
| 173 if (!referenced_scene) |
270 unavailable_sender.Run(resource_id); | 174 unavailable_sender.Run(resource_id); |
271 } | 175 return new SceneResourceDef(scene_token, referenced_scene); |
272 return new SceneResourceDef(referenced_scene); | |
273 } | 176 } |
274 | 177 |
275 if (resource_decl->is_mailbox_texture()) { | 178 if (resource_decl->is_mailbox_texture()) { |
276 auto& mailbox_texture_resource_decl = resource_decl->get_mailbox_texture(); | 179 auto& mailbox_texture_resource_decl = resource_decl->get_mailbox_texture(); |
277 DCHECK(mailbox_texture_resource_decl->mailbox_name.size() == | 180 DCHECK(mailbox_texture_resource_decl->mailbox_name.size() == |
278 GL_MAILBOX_SIZE_CHROMIUM); | 181 GL_MAILBOX_SIZE_CHROMIUM); |
279 DCHECK(mailbox_texture_resource_decl->size); | 182 DCHECK(mailbox_texture_resource_decl->size); |
280 int32_t width = mailbox_texture_resource_decl->size->width; | 183 |
281 int32_t height = mailbox_texture_resource_decl->size->height; | 184 const int32_t width = mailbox_texture_resource_decl->size->width; |
| 185 const int32_t height = mailbox_texture_resource_decl->size->height; |
282 if (width < 1 || width > kMaxTextureWidth || height < 1 || | 186 if (width < 1 || width > kMaxTextureWidth || height < 1 || |
283 height > kMaxTextureHeight) { | 187 height > kMaxTextureHeight) { |
284 err << "MailboxTexture resource has invalid size: " | 188 err << "MailboxTexture resource has invalid size: " |
285 << "resource_id=" << resource_id << ", width=" << width | 189 << "resource_id=" << resource_id << ", width=" << width |
286 << ", height=" << height; | 190 << ", height=" << height; |
287 return nullptr; | 191 return nullptr; |
288 } | 192 } |
| 193 const GLbyte* const mailbox_name = reinterpret_cast<GLbyte*>( |
| 194 mailbox_texture_resource_decl->mailbox_name.data()); |
| 195 const GLuint sync_point = mailbox_texture_resource_decl->sync_point; |
| 196 |
289 std::shared_ptr<RenderImage> image = RenderImage::CreateFromMailboxTexture( | 197 std::shared_ptr<RenderImage> image = RenderImage::CreateFromMailboxTexture( |
290 reinterpret_cast<GLbyte*>( | 198 mailbox_name, sync_point, width, height, |
291 mailbox_texture_resource_decl->mailbox_name.data()), | |
292 mailbox_texture_resource_decl->sync_point, width, height, | |
293 base::MessageLoop::current()->task_runner(), | 199 base::MessageLoop::current()->task_runner(), |
294 base::Bind( | 200 base::Bind( |
295 &ReleaseMailboxTexture, | 201 &ReleaseMailboxTexture, |
296 base::Passed( | 202 base::Passed( |
297 mojo::gfx::composition::MailboxTextureCallbackPtr::Create( | 203 mojo::gfx::composition::MailboxTextureCallbackPtr::Create( |
298 std::move(mailbox_texture_resource_decl->callback))))); | 204 std::move(mailbox_texture_resource_decl->callback))))); |
299 if (!image) { | 205 if (!image) { |
300 err << "Could not create MailboxTexture"; | 206 err << "Could not create MailboxTexture"; |
301 return nullptr; | 207 return nullptr; |
302 } | 208 } |
303 return new ImageResourceDef(image); | 209 return new ImageResourceDef(image); |
304 } | 210 } |
305 | 211 |
306 err << "Unsupported resource type: resource_id=" << resource_id; | 212 err << "Unsupported resource type: resource_id=" << resource_id; |
307 return nullptr; | 213 return nullptr; |
308 } | 214 } |
309 | 215 |
310 NodeDef* SceneDef::CreateNode(uint32_t node_id, | 216 scoped_refptr<const NodeDef> SceneDef::CreateNode( |
311 mojo::gfx::composition::NodePtr node_decl, | 217 uint32_t node_id, |
312 std::ostream& err) { | 218 mojo::gfx::composition::NodePtr node_decl, |
| 219 std::ostream& err) { |
313 DCHECK(node_decl); | 220 DCHECK(node_decl); |
314 | 221 |
315 NodeOp* op = nullptr; | 222 mojo::TransformPtr content_transform = node_decl->content_transform.Pass(); |
316 if (node_decl->op) { | 223 mojo::RectPtr content_clip = node_decl->content_clip.Pass(); |
317 op = CreateNodeOp(node_id, node_decl->op.Pass(), err); | 224 const mojo::gfx::composition::Node::Combinator combinator = |
318 if (!op) | 225 node_decl->combinator; |
319 return nullptr; | 226 const std::vector<uint32_t>& child_node_ids = |
| 227 node_decl->child_node_ids.storage(); |
| 228 |
| 229 if (!node_decl->op) { |
| 230 return new NodeDef(node_id, content_transform.Pass(), content_clip.Pass(), |
| 231 combinator, child_node_ids); |
320 } | 232 } |
321 | 233 |
322 return new NodeDef(node_id, node_decl->content_transform.Pass(), | 234 if (node_decl->op->is_rect()) { |
323 node_decl->content_clip.Pass(), node_decl->hit_id, | 235 auto& rect_node_decl = node_decl->op->get_rect(); |
324 node_decl->combinator, node_decl->child_node_ids.storage(), | 236 DCHECK(rect_node_decl->content_rect); |
325 op); | 237 DCHECK(rect_node_decl->color); |
326 } | |
327 | 238 |
328 NodeOp* SceneDef::CreateNodeOp(uint32_t node_id, | 239 const mojo::Rect& content_rect = *rect_node_decl->content_rect; |
329 mojo::gfx::composition::NodeOpPtr node_op_decl, | 240 const mojo::gfx::composition::Color& color = *rect_node_decl->color; |
330 std::ostream& err) { | 241 return new RectNodeDef(node_id, content_transform.Pass(), |
331 DCHECK(node_op_decl); | 242 content_clip.Pass(), combinator, child_node_ids, |
332 | 243 content_rect, color); |
333 if (node_op_decl->is_rect()) { | |
334 auto& rect_node_op_decl = node_op_decl->get_rect(); | |
335 DCHECK(rect_node_op_decl->content_rect); | |
336 DCHECK(rect_node_op_decl->color); | |
337 return new RectNodeOp(*rect_node_op_decl->content_rect, | |
338 *rect_node_op_decl->color); | |
339 } | 244 } |
340 | 245 |
341 if (node_op_decl->is_image()) { | 246 if (node_decl->op->is_image()) { |
342 auto& image_node_op_decl = node_op_decl->get_image(); | 247 auto& image_node_decl = node_decl->op->get_image(); |
343 DCHECK(image_node_op_decl->content_rect); | 248 DCHECK(image_node_decl->content_rect); |
344 return new ImageNodeOp(*image_node_op_decl->content_rect, | 249 |
345 image_node_op_decl->image_rect.Pass(), | 250 const mojo::Rect& content_rect = *image_node_decl->content_rect; |
346 image_node_op_decl->image_resource_id, | 251 mojo::RectPtr image_rect = image_node_decl->image_rect.Pass(); |
347 image_node_op_decl->blend.Pass()); | 252 const uint32 image_resource_id = image_node_decl->image_resource_id; |
| 253 mojo::gfx::composition::BlendPtr blend = image_node_decl->blend.Pass(); |
| 254 return new ImageNodeDef(node_id, content_transform.Pass(), |
| 255 content_clip.Pass(), combinator, child_node_ids, |
| 256 content_rect, image_rect.Pass(), image_resource_id, |
| 257 blend.Pass()); |
348 } | 258 } |
349 | 259 |
350 if (node_op_decl->is_scene()) { | 260 if (node_decl->op->is_scene()) { |
351 auto& scene_node_op_decl = node_op_decl->get_scene(); | 261 auto& scene_node_decl = node_decl->op->get_scene(); |
352 return new SceneNodeOp(scene_node_op_decl->scene_resource_id, | 262 |
353 scene_node_op_decl->scene_version); | 263 const uint32_t scene_resource_id = scene_node_decl->scene_resource_id; |
| 264 const uint32_t scene_version = scene_node_decl->scene_version; |
| 265 return new SceneNodeDef(node_id, content_transform.Pass(), |
| 266 content_clip.Pass(), combinator, child_node_ids, |
| 267 scene_resource_id, scene_version); |
354 } | 268 } |
355 | 269 |
356 if (node_op_decl->is_layer()) { | 270 if (node_decl->op->is_layer()) { |
357 auto& layer_node_op_decl = node_op_decl->get_layer(); | 271 auto& layer_node_decl = node_decl->op->get_layer(); |
358 DCHECK(layer_node_op_decl->layer_size); | 272 DCHECK(layer_node_decl->layer_size); |
359 return new LayerNodeOp(*layer_node_op_decl->layer_size, | 273 |
360 layer_node_op_decl->blend.Pass()); | 274 const mojo::Size& layer_size = *layer_node_decl->layer_size; |
| 275 mojo::gfx::composition::BlendPtr blend = layer_node_decl->blend.Pass(); |
| 276 return new LayerNodeDef(node_id, content_transform.Pass(), |
| 277 content_clip.Pass(), combinator, child_node_ids, |
| 278 layer_size, blend.Pass()); |
361 } | 279 } |
362 | 280 |
363 err << "Unsupported node op type: node_id=" << node_id | 281 err << "Unsupported node op type: node_id=" << node_id |
364 << ", node_op=" << node_op_decl; | 282 << ", node_op=" << node_decl->op; |
365 return nullptr; | 283 return nullptr; |
366 } | 284 } |
367 | 285 |
368 NodeDef* SceneDef::FindNode(uint32_t node_id) { | 286 const NodeDef* SceneDef::FindNode(uint32_t node_id) const { |
369 auto it = nodes_.find(node_id); | 287 auto it = nodes_.find(node_id); |
370 return it != nodes_.end() ? it->second.get() : nullptr; | 288 return it != nodes_.end() ? it->second.get() : nullptr; |
371 } | 289 } |
372 | 290 |
373 ResourceDef* SceneDef::FindResource(uint32_t resource_id, | 291 const ResourceDef* SceneDef::FindResource(uint32_t resource_id) const { |
374 ResourceDef::Type resource_type) { | |
375 auto it = resources_.find(resource_id); | 292 auto it = resources_.find(resource_id); |
376 return it != resources_.end() && it->second->type() == resource_type | 293 return it != resources_.end() ? it->second.get() : nullptr; |
377 ? it->second.get() | |
378 : nullptr; | |
379 } | 294 } |
380 | 295 |
381 std::string SceneDef::FormattedLabel() { | 296 const SceneContent* SceneDef::FindContent(uint32_t version) const { |
382 if (formatted_label_cache_.empty()) { | 297 if (!content_) |
383 formatted_label_cache_ = | 298 return nullptr; |
384 label_.empty() | 299 |
385 ? base::StringPrintf("<%d/%d>", scene_token_->value, version_) | 300 // TODO(jeffbrown): Consider briefly caching older versions to allow them |
386 : base::StringPrintf("<%d:%s/%d>", scene_token_->value, | 301 // to be used to provide alternate content for node combinators. |
387 label_.c_str(), version_); | 302 if (version != mojo::gfx::composition::kSceneVersionNone && |
388 } | 303 version != content_->version() && |
389 return formatted_label_cache_; | 304 content_->version() != mojo::gfx::composition::kSceneVersionNone) |
| 305 return nullptr; |
| 306 return content_.get(); |
390 } | 307 } |
391 | 308 |
392 SceneDef::Publication::Publication( | 309 SceneDef::Publication::Publication( |
393 mojo::gfx::composition::SceneMetadataPtr metadata) | 310 mojo::gfx::composition::SceneMetadataPtr metadata) |
394 : metadata(metadata.Pass()) { | 311 : metadata(metadata.Pass()) { |
395 DCHECK(this->metadata); | 312 DCHECK(this->metadata); |
396 } | 313 } |
397 | 314 |
398 SceneDef::Publication::~Publication() {} | 315 SceneDef::Publication::~Publication() {} |
399 | 316 |
400 } // namespace compositor | 317 } // namespace compositor |
OLD | NEW |