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

Side by Side Diff: services/gfx/compositor/graph/scene_def.cc

Issue 1749063002: Mozart: Improve internal scene graph representation. (Closed) Base URL: git@github.com:domokit/mojo.git@moz-0
Patch Set: avoid unnecessary hashtable lookups Created 4 years, 9 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
« no previous file with comments | « services/gfx/compositor/graph/scene_def.h ('k') | services/gfx/compositor/graph/scene_label.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "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
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
OLDNEW
« no previous file with comments | « services/gfx/compositor/graph/scene_def.h ('k') | services/gfx/compositor/graph/scene_label.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698