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/node_def.h" | 5 #include "services/gfx/compositor/graph/node_def.h" |
6 | 6 |
7 #include <ostream> | |
8 | |
7 #include "base/logging.h" | 9 #include "base/logging.h" |
8 #include "base/strings/stringprintf.h" | |
9 #include "mojo/services/gfx/composition/cpp/formatting.h" | 10 #include "mojo/services/gfx/composition/cpp/formatting.h" |
10 #include "mojo/skia/type_converters.h" | 11 #include "mojo/skia/type_converters.h" |
12 #include "services/gfx/compositor/graph/scene_content.h" | |
11 #include "services/gfx/compositor/graph/scene_def.h" | 13 #include "services/gfx/compositor/graph/scene_def.h" |
12 #include "services/gfx/compositor/graph/snapshot.h" | 14 #include "services/gfx/compositor/graph/snapshot.h" |
13 #include "services/gfx/compositor/render/render_image.h" | 15 #include "services/gfx/compositor/render/render_image.h" |
14 #include "services/gfx/compositor/render/render_layer.h" | 16 #include "third_party/skia/include/core/SkCanvas.h" |
17 #include "third_party/skia/include/core/SkColor.h" | |
18 #include "third_party/skia/include/core/SkPaint.h" | |
19 #include "third_party/skia/include/core/SkRect.h" | |
15 | 20 |
16 namespace compositor { | 21 namespace compositor { |
17 namespace { | 22 namespace { |
18 SkColor MakeSkColor(const mojo::gfx::composition::Color& color) { | 23 SkColor MakeSkColor(const mojo::gfx::composition::Color& color) { |
19 return SkColorSetARGBInline(color.alpha, color.red, color.green, color.blue); | 24 return SkColorSetARGBInline(color.alpha, color.red, color.green, color.blue); |
20 } | 25 } |
21 | 26 |
22 SkPaint MakePaintForBlend(const mojo::gfx::composition::Blend& blend) { | 27 void SetPaintForBlend(SkPaint* paint, mojo::gfx::composition::Blend* blend) { |
23 SkPaint result; | 28 DCHECK(paint); |
24 result.setAlpha(blend.alpha); | 29 if (blend) |
25 return result; | 30 paint->setAlpha(blend->alpha); |
26 } | 31 } |
27 } // namespace | 32 } // namespace |
28 | 33 |
29 NodeDef::NodeDef(uint32_t node_id, | 34 NodeDef::NodeDef(uint32_t node_id, |
30 mojo::TransformPtr content_transform, | 35 mojo::TransformPtr content_transform, |
31 mojo::RectPtr content_clip, | 36 mojo::RectPtr content_clip, |
32 uint32_t hit_id, | |
33 Combinator combinator, | 37 Combinator combinator, |
34 const std::vector<uint32_t>& child_node_ids, | 38 const std::vector<uint32_t>& child_node_ids) |
35 NodeOp* op) | |
36 : node_id_(node_id), | 39 : node_id_(node_id), |
37 content_transform_(content_transform.Pass()), | 40 content_transform_(content_transform.Pass()), |
38 content_clip_(content_clip.Pass()), | 41 content_clip_(content_clip.Pass()), |
39 hit_id_(hit_id), | |
40 combinator_(combinator), | 42 combinator_(combinator), |
41 child_node_ids_(child_node_ids), | 43 child_node_ids_(child_node_ids) {} |
42 op_(op) {} | |
43 | 44 |
44 NodeDef::~NodeDef() {} | 45 NodeDef::~NodeDef() {} |
45 | 46 |
46 bool NodeDef::Validate(SceneDef* scene, std::ostream& err) { | 47 std::string NodeDef::FormattedLabel(const SceneContent* content) const { |
47 child_nodes_.clear(); | 48 return content->FormattedLabelForNode(node_id_); |
48 for (uint32_t child_node_id : child_node_ids_) { | 49 } |
49 NodeDef* child_node = scene->FindNode(child_node_id); | 50 |
50 if (!child_node) { | 51 bool NodeDef::RecordContent(SceneContentBuilder* builder) const { |
51 err << "Node refers to unknown child: " << FormattedLabel(scene) | 52 DCHECK(builder); |
52 << ", child_node_id=" << child_node_id; | 53 |
54 for (const auto& child_node_id : child_node_ids_) { | |
55 if (!builder->RequireNode(child_node_id, node_id_)) | |
53 return false; | 56 return false; |
54 } | 57 } |
55 child_nodes_.push_back(child_node); | |
56 } | |
57 | |
58 return !op_ || op_->Validate(scene, this, err); | |
59 } | |
60 | |
61 bool NodeDef::Snapshot(SnapshotBuilder* snapshot_builder, | |
62 RenderLayerBuilder* layer_builder, | |
63 SceneDef* scene) { | |
64 DCHECK(snapshot_builder); | |
65 DCHECK(layer_builder); | |
66 DCHECK(scene); | |
67 | |
68 // Detect cycles. | |
69 if (visited_) { | |
70 if (snapshot_builder->block_log()) { | |
71 *snapshot_builder->block_log() | |
72 << "Node blocked due to recursive cycle: " << FormattedLabel(scene) | |
73 << std::endl; | |
74 } | |
75 return false; | |
76 } | |
77 | |
78 // Snapshot the contents of the node. | |
79 visited_ = true; | |
80 bool success = SnapshotInner(snapshot_builder, layer_builder, scene); | |
81 visited_ = false; | |
82 return success; | |
83 } | |
84 | |
85 bool NodeDef::SnapshotInner(SnapshotBuilder* snapshot_builder, | |
86 RenderLayerBuilder* layer_builder, | |
87 SceneDef* scene) { | |
88 // TODO(jeffbrown): Frequently referenced and reused nodes, especially | |
89 // layer nodes, may benefit from caching. | |
90 layer_builder->PushNode(node_id_, hit_id_); | |
91 if (content_transform_) | |
92 layer_builder->ApplyTransform(content_transform_.To<SkMatrix>()); | |
93 if (content_clip_) | |
94 layer_builder->ApplyClip(content_clip_->To<SkRect>()); | |
95 | |
96 bool success = | |
97 op_ ? op_->Snapshot(snapshot_builder, layer_builder, scene, this) | |
98 : SnapshotChildren(snapshot_builder, layer_builder, scene); | |
99 if (!success) | |
100 return false; | |
101 | |
102 layer_builder->PopNode(); | |
103 return true; | 58 return true; |
104 } | 59 } |
105 | 60 |
106 bool NodeDef::SnapshotChildren(SnapshotBuilder* snapshot_builder, | 61 Snapshot::Disposition NodeDef::RecordSnapshot(const SceneContent* content, |
107 RenderLayerBuilder* layer_builder, | 62 SnapshotBuilder* builder) const { |
108 SceneDef* scene) { | 63 DCHECK(content); |
109 DCHECK(snapshot_builder); | 64 DCHECK(builder); |
110 DCHECK(layer_builder); | |
111 DCHECK(scene); | |
112 | 65 |
113 switch (combinator_) { | 66 switch (combinator_) { |
114 // MERGE: All or nothing. | 67 // MERGE: All or nothing. |
115 case Combinator::MERGE: { | 68 case Combinator::MERGE: { |
116 for (NodeDef* child_node : child_nodes_) { | 69 for (uint32_t child_node_id : child_node_ids_) { |
117 if (!child_node->Snapshot(snapshot_builder, layer_builder, scene)) { | 70 const NodeDef* child_node = content->GetNode(child_node_id); |
118 if (snapshot_builder->block_log()) { | 71 DCHECK(child_node); |
119 *snapshot_builder->block_log() | 72 Snapshot::Disposition disposition = |
73 builder->SnapshotNode(child_node, content); | |
74 if (disposition == Snapshot::Disposition::kCycle) | |
75 return disposition; | |
76 if (disposition == Snapshot::Disposition::kBlocked) { | |
77 if (builder->block_log()) { | |
78 *builder->block_log() | |
120 << "Node with MERGE combinator blocked since " | 79 << "Node with MERGE combinator blocked since " |
121 "one of its children is blocked: " | 80 "one of its children is blocked: " |
122 << FormattedLabel(scene) << ", blocked child " | 81 << FormattedLabel(content) << ", blocked child " |
123 << child_node->FormattedLabel(scene) << std::endl; | 82 << child_node->FormattedLabel(content) << std::endl; |
124 } | 83 } |
125 return false; // blocked | 84 return disposition; |
126 } | 85 } |
127 } | 86 } |
128 return true; | 87 return Snapshot::Disposition::kSuccess; |
129 } | 88 } |
130 | 89 |
131 // PRUNE: Silently discard blocked children. | 90 // PRUNE: Silently discard blocked children. |
132 case Combinator::PRUNE: { | 91 case Combinator::PRUNE: { |
133 for (NodeDef* child_node : child_nodes_) { | 92 for (uint32_t child_node_id : child_node_ids_) { |
134 RenderLayerBuilder child_layer_builder; | 93 const NodeDef* child_node = content->GetNode(child_node_id); |
135 if (child_node->Snapshot(snapshot_builder, &child_layer_builder, | 94 DCHECK(child_node); |
136 scene)) { | 95 Snapshot::Disposition disposition = |
137 layer_builder->DrawLayer(child_layer_builder.Build()); | 96 builder->SnapshotNode(child_node, content); |
138 } | 97 if (disposition == Snapshot::Disposition::kCycle) |
139 } | 98 return disposition; |
140 return true; | 99 } |
100 return Snapshot::Disposition::kSuccess; | |
141 } | 101 } |
142 | 102 |
143 // FALLBACK: Keep only the first unblocked child. | 103 // FALLBACK: Keep only the first unblocked child. |
144 case Combinator::FALLBACK: { | 104 case Combinator::FALLBACK: { |
145 if (child_nodes_.empty()) | 105 if (child_node_ids_.empty()) |
106 return Snapshot::Disposition::kSuccess; | |
107 for (uint32_t child_node_id : child_node_ids_) { | |
108 const NodeDef* child_node = content->GetNode(child_node_id); | |
109 DCHECK(child_node); | |
110 Snapshot::Disposition disposition = | |
111 builder->SnapshotNode(child_node, content); | |
112 if (disposition != Snapshot::Disposition::kBlocked) | |
113 return disposition; | |
114 } | |
115 if (builder->block_log()) { | |
116 *builder->block_log() << "Node with FALLBACK combinator blocked since " | |
117 "all of its children are blocked: " | |
118 << FormattedLabel(content) << std::endl; | |
119 } | |
120 return Snapshot::Disposition::kBlocked; | |
121 } | |
122 | |
123 default: { | |
124 if (builder->block_log()) { | |
125 *builder->block_log() | |
126 << "Unrecognized combinator: " << FormattedLabel(content) | |
127 << std::endl; | |
128 } | |
129 return Snapshot::Disposition::kBlocked; | |
130 } | |
131 } | |
132 } | |
133 | |
134 template <typename Func> | |
135 void NodeDef::TraverseSnapshottedChildren(const SceneContent* content, | |
136 const Snapshot* snapshot, | |
137 const Func& func) const { | |
138 DCHECK(content); | |
139 DCHECK(snapshot); | |
140 | |
141 switch (combinator_) { | |
142 // MERGE: All or nothing. | |
143 case Combinator::MERGE: { | |
144 for (uint32_t child_node_id : child_node_ids_) { | |
145 const NodeDef* child_node = content->GetNode(child_node_id); | |
146 DCHECK(child_node); | |
147 DCHECK(!snapshot->IsBlocked(child_node)); | |
148 if (!func(child_node)) | |
149 return; | |
150 } | |
151 return; | |
152 } | |
153 | |
154 // PRUNE: Silently discard blocked children. | |
155 case Combinator::PRUNE: { | |
156 for (uint32_t child_node_id : child_node_ids_) { | |
157 const NodeDef* child_node = content->GetNode(child_node_id); | |
158 DCHECK(child_node); | |
159 if (!snapshot->IsBlocked(child_node) && !func(child_node)) | |
160 return; | |
161 } | |
162 return; | |
163 } | |
164 | |
165 // FALLBACK: Keep only the first unblocked child. | |
166 case Combinator::FALLBACK: { | |
167 if (child_node_ids_.empty()) | |
168 return; | |
169 for (uint32_t child_node_id : child_node_ids_) { | |
170 const NodeDef* child_node = content->GetNode(child_node_id); | |
171 DCHECK(child_node); | |
172 if (!snapshot->IsBlocked(child_node)) { | |
173 func(child_node); // don't care about the result because we | |
174 return; // always stop after the first one | |
175 } | |
176 } | |
177 NOTREACHED(); | |
178 return; | |
179 } | |
180 | |
181 default: { | |
182 NOTREACHED(); | |
183 return; | |
184 } | |
185 } | |
186 } | |
187 | |
188 void NodeDef::RecordPicture(const SceneContent* content, | |
189 const Snapshot* snapshot, | |
190 SkCanvas* canvas) const { | |
191 DCHECK(content); | |
192 DCHECK(snapshot); | |
193 DCHECK(canvas); | |
194 | |
195 const bool must_save = content_transform_ || content_clip_; | |
196 if (must_save) { | |
197 canvas->save(); | |
198 if (content_transform_) | |
199 canvas->concat(content_transform_.To<SkMatrix>()); | |
200 if (content_clip_) | |
201 canvas->clipRect(content_clip_->To<SkRect>()); | |
202 } | |
203 | |
204 RecordPictureInner(content, snapshot, canvas); | |
205 | |
206 if (must_save) | |
207 canvas->restore(); | |
208 } | |
209 | |
210 void NodeDef::RecordPictureInner(const SceneContent* content, | |
211 const Snapshot* snapshot, | |
212 SkCanvas* canvas) const { | |
213 DCHECK(content); | |
214 DCHECK(snapshot); | |
215 DCHECK(canvas); | |
216 | |
217 TraverseSnapshottedChildren( | |
218 content, snapshot, [=](const NodeDef* child_node) -> bool { | |
abarth
2016/03/01 17:21:26
Is `[=]` permitted by the style guide?
jeffbrown
2016/03/02 00:32:16
Huh, apparently not. *sigh*
| |
219 child_node->RecordPicture(content, snapshot, canvas); | |
146 return true; | 220 return true; |
147 for (NodeDef* child_node : child_nodes_) { | 221 }); |
148 RenderLayerBuilder child_layer_builder; | 222 } |
149 if (child_node->Snapshot(snapshot_builder, &child_layer_builder, | 223 |
150 scene)) { | 224 RectNodeDef::RectNodeDef(uint32_t node_id, |
151 layer_builder->DrawLayer(child_layer_builder.Build()); | 225 mojo::TransformPtr content_transform, |
152 return true; | 226 mojo::RectPtr content_clip, |
153 } | 227 Combinator combinator, |
154 } | 228 const std::vector<uint32_t>& child_node_ids, |
155 if (snapshot_builder->block_log()) { | 229 const mojo::Rect& content_rect, |
156 *snapshot_builder->block_log() | 230 const mojo::gfx::composition::Color& color) |
157 << "Node with FALLBACK combinator blocked since " | 231 : NodeDef(node_id, |
158 "all of its children are blocked: " | 232 content_transform.Pass(), |
159 << FormattedLabel(scene) << std::endl; | 233 content_clip.Pass(), |
160 } | 234 combinator, |
161 return false; // blocked | 235 child_node_ids), |
162 } | 236 content_rect_(content_rect), |
163 | 237 color_(color) {} |
164 default: { | 238 |
165 if (snapshot_builder->block_log()) { | 239 RectNodeDef::~RectNodeDef() {} |
166 *snapshot_builder->block_log() | 240 |
167 << "Unrecognized combinator: " << FormattedLabel(scene) | 241 void RectNodeDef::RecordPictureInner(const SceneContent* content, |
168 << std::endl; | 242 const Snapshot* snapshot, |
169 } | 243 SkCanvas* canvas) const { |
170 return false; | 244 DCHECK(content); |
171 } | 245 DCHECK(snapshot); |
172 } | 246 DCHECK(canvas); |
173 } | 247 |
174 | |
175 std::string NodeDef::FormattedLabel(SceneDef* scene) { | |
176 return base::StringPrintf("%s[%d]", scene->FormattedLabel().c_str(), | |
177 node_id_); | |
178 } | |
179 | |
180 bool NodeOp::Validate(SceneDef* scene, NodeDef* node, std::ostream& err) { | |
181 return true; | |
182 } | |
183 | |
184 RectNodeOp::RectNodeOp(const mojo::Rect& content_rect, | |
185 const mojo::gfx::composition::Color& color) | |
186 : content_rect_(content_rect), color_(color) {} | |
187 | |
188 RectNodeOp::~RectNodeOp() {} | |
189 | |
190 bool RectNodeOp::Snapshot(SnapshotBuilder* snapshot_builder, | |
191 RenderLayerBuilder* layer_builder, | |
192 SceneDef* scene, | |
193 NodeDef* node) { | |
194 SkPaint paint; | 248 SkPaint paint; |
195 paint.setColor(MakeSkColor(color_)); | 249 paint.setColor(MakeSkColor(color_)); |
196 layer_builder->DrawRect(content_rect_.To<SkRect>(), paint); | 250 canvas->drawRect(content_rect_.To<SkRect>(), paint); |
197 | 251 |
198 return node->SnapshotChildren(snapshot_builder, layer_builder, scene); | 252 NodeDef::RecordPictureInner(content, snapshot, canvas); |
199 } | 253 } |
200 | 254 |
201 ImageNodeOp::ImageNodeOp(const mojo::Rect& content_rect, | 255 ImageNodeDef::ImageNodeDef(uint32_t node_id, |
202 mojo::RectPtr image_rect, | 256 mojo::TransformPtr content_transform, |
203 uint32 image_resource_id, | 257 mojo::RectPtr content_clip, |
204 mojo::gfx::composition::BlendPtr blend) | 258 Combinator combinator, |
205 : content_rect_(content_rect), | 259 const std::vector<uint32_t>& child_node_ids, |
260 const mojo::Rect& content_rect, | |
261 mojo::RectPtr image_rect, | |
262 uint32 image_resource_id, | |
263 mojo::gfx::composition::BlendPtr blend) | |
264 : NodeDef(node_id, | |
265 content_transform.Pass(), | |
266 content_clip.Pass(), | |
267 combinator, | |
268 child_node_ids), | |
269 content_rect_(content_rect), | |
206 image_rect_(image_rect.Pass()), | 270 image_rect_(image_rect.Pass()), |
207 image_resource_id_(image_resource_id), | 271 image_resource_id_(image_resource_id), |
208 blend_(blend.Pass()) {} | 272 blend_(blend.Pass()) {} |
209 | 273 |
210 ImageNodeOp::~ImageNodeOp() {} | 274 ImageNodeDef::~ImageNodeDef() {} |
211 | 275 |
212 bool ImageNodeOp::Validate(SceneDef* scene, NodeDef* node, std::ostream& err) { | 276 bool ImageNodeDef::RecordContent(SceneContentBuilder* builder) const { |
213 image_resource_ = scene->FindImageResource(image_resource_id_); | 277 DCHECK(builder); |
214 if (!image_resource_) { | 278 |
215 err << "Node refers to unknown or invalid image resource: " | 279 return NodeDef::RecordContent(builder) && |
216 << node->FormattedLabel(scene) | 280 builder->RequireResource(image_resource_id_, ResourceDef::Type::kImage, |
217 << ", image_resource_id=" << image_resource_id_; | 281 node_id()); |
218 return false; | 282 } |
219 } | 283 |
220 return true; | 284 void ImageNodeDef::RecordPictureInner(const SceneContent* content, |
221 } | 285 const Snapshot* snapshot, |
222 | 286 SkCanvas* canvas) const { |
223 bool ImageNodeOp::Snapshot(SnapshotBuilder* snapshot_builder, | 287 DCHECK(content); |
224 RenderLayerBuilder* layer_builder, | 288 DCHECK(snapshot); |
225 SceneDef* scene, | 289 DCHECK(canvas); |
226 NodeDef* node) { | 290 |
227 DCHECK(image_resource_); | 291 auto image_resource = static_cast<const ImageResourceDef*>( |
228 | 292 content->GetResource(image_resource_id_, ResourceDef::Type::kImage)); |
229 if (!image_resource_->image()) { | 293 DCHECK(image_resource); |
230 if (snapshot_builder->block_log()) { | 294 |
231 *snapshot_builder->block_log() | 295 SkPaint paint; |
232 << "Node blocked due to its referenced image " | 296 SetPaintForBlend(&paint, blend_.get()); |
233 "resource being unavailable: " | 297 |
234 << node->FormattedLabel(scene) << std::endl; | 298 canvas->drawImageRect(image_resource->image()->image().get(), |
235 } | 299 image_rect_ |
236 return false; | 300 ? image_rect_->To<SkRect>() |
237 } | 301 : SkRect::MakeWH(image_resource->image()->width(), |
238 | 302 image_resource->image()->height()), |
239 layer_builder->DrawImage( | 303 content_rect_.To<SkRect>(), &paint); |
240 image_resource_->image(), content_rect_.To<SkRect>(), | 304 |
241 image_rect_ ? image_rect_->To<SkRect>() | 305 NodeDef::RecordPictureInner(content, snapshot, canvas); |
242 : SkRect::MakeWH(image_resource_->image()->width(), | 306 } |
243 image_resource_->image()->height()), | 307 |
244 blend_ ? MakePaintForBlend(*blend_) : SkPaint()); | 308 SceneNodeDef::SceneNodeDef(uint32_t node_id, |
245 | 309 mojo::TransformPtr content_transform, |
246 return node->SnapshotChildren(snapshot_builder, layer_builder, scene); | 310 mojo::RectPtr content_clip, |
247 } | 311 Combinator combinator, |
248 | 312 const std::vector<uint32_t>& child_node_ids, |
249 SceneNodeOp::SceneNodeOp(uint32_t scene_resource_id, uint32_t scene_version) | 313 uint32_t scene_resource_id, |
250 : scene_resource_id_(scene_resource_id), scene_version_(scene_version) {} | 314 uint32_t scene_version) |
251 | 315 : NodeDef(node_id, |
252 SceneNodeOp::~SceneNodeOp() {} | 316 content_transform.Pass(), |
253 | 317 content_clip.Pass(), |
254 bool SceneNodeOp::Validate(SceneDef* scene, NodeDef* node, std::ostream& err) { | 318 combinator, |
255 scene_resource_ = scene->FindSceneResource(scene_resource_id_); | 319 child_node_ids), |
256 if (!scene_resource_) { | 320 scene_resource_id_(scene_resource_id), |
257 err << "Node refers to unknown or invalid scene resource: " | 321 scene_version_(scene_version) {} |
258 << node->FormattedLabel(scene) | 322 |
259 << ", scene_resource_id=" << scene_resource_id_; | 323 SceneNodeDef::~SceneNodeDef() {} |
260 return false; | 324 |
261 } | 325 bool SceneNodeDef::RecordContent(SceneContentBuilder* builder) const { |
262 return true; | 326 DCHECK(builder); |
263 } | 327 |
264 | 328 return NodeDef::RecordContent(builder) && |
265 bool SceneNodeOp::Snapshot(SnapshotBuilder* snapshot_builder, | 329 builder->RequireResource(scene_resource_id_, ResourceDef::Type::kScene, |
266 RenderLayerBuilder* layer_builder, | 330 node_id()); |
267 SceneDef* scene, | 331 } |
268 NodeDef* node) { | 332 |
269 DCHECK(scene_resource_); | 333 Snapshot::Disposition SceneNodeDef::RecordSnapshot( |
270 | 334 const SceneContent* content, |
271 SceneDef* referenced_scene = scene_resource_->referenced_scene(); | 335 SnapshotBuilder* builder) const { |
336 DCHECK(content); | |
337 DCHECK(builder); | |
338 | |
339 auto scene_resource = static_cast<const SceneResourceDef*>( | |
340 content->GetResource(scene_resource_id_, ResourceDef::Type::kScene)); | |
341 DCHECK(scene_resource); | |
342 | |
343 SceneDef* referenced_scene = scene_resource->referenced_scene().get(); | |
272 if (!referenced_scene) { | 344 if (!referenced_scene) { |
273 if (snapshot_builder->block_log()) { | 345 if (builder->block_log()) { |
274 *snapshot_builder->block_log() | 346 *builder->block_log() |
275 << "Node blocked due to its referenced scene " | 347 << "Scene node blocked because its referenced scene is unavailable: " |
276 "resource being unavailable: " | 348 << FormattedLabel(content) << std::endl; |
277 << node->FormattedLabel(scene) << std::endl; | 349 } |
278 } | 350 return Snapshot::Disposition::kBlocked; |
279 return false; | 351 } |
280 } | 352 |
281 | 353 Snapshot::Disposition disposition = |
282 uint32_t actual_version = referenced_scene->version(); | 354 builder->SnapshotScene(referenced_scene, scene_version_, this, content); |
283 if (scene_version_ != mojo::gfx::composition::kSceneVersionNone && | 355 if (disposition != Snapshot::Disposition::kSuccess) |
284 actual_version != mojo::gfx::composition::kSceneVersionNone && | 356 return disposition; |
285 scene_version_ != actual_version) { | 357 return NodeDef::RecordSnapshot(content, builder); |
286 if (snapshot_builder->block_log()) { | 358 } |
287 *snapshot_builder->block_log() | 359 |
288 << "Node blocked due to its referenced scene " | 360 void SceneNodeDef::RecordPictureInner(const SceneContent* content, |
289 "resource not having the desired version: " | 361 const Snapshot* snapshot, |
290 << node->FormattedLabel(scene) | 362 SkCanvas* canvas) const { |
291 << ", requested_version=" << scene_version_ | 363 DCHECK(content); |
292 << ", actual_version=" << actual_version << std::endl; | 364 DCHECK(snapshot); |
293 } | 365 DCHECK(canvas); |
294 return false; | 366 |
295 } | 367 const SceneContent* resolved_content = |
296 | 368 snapshot->GetResolvedSceneContent(this); |
297 if (!referenced_scene->Snapshot(snapshot_builder, layer_builder)) | 369 DCHECK(resolved_content); |
298 return false; | 370 |
299 | 371 const NodeDef* root_node = resolved_content->GetRootNodeIfExists(); |
300 return node->SnapshotChildren(snapshot_builder, layer_builder, scene); | 372 DCHECK(root_node); // must have a root otherwise would have been blocked |
301 } | 373 root_node->RecordPicture(resolved_content, snapshot, canvas); |
302 | 374 |
303 LayerNodeOp::LayerNodeOp(const mojo::Size& size, | 375 NodeDef::RecordPictureInner(content, snapshot, canvas); |
304 mojo::gfx::composition::BlendPtr blend) | 376 } |
305 : size_(size), blend_(blend.Pass()) {} | 377 |
306 | 378 LayerNodeDef::LayerNodeDef(uint32_t node_id, |
307 LayerNodeOp::~LayerNodeOp() {} | 379 mojo::TransformPtr content_transform, |
308 | 380 mojo::RectPtr content_clip, |
309 bool LayerNodeOp::Snapshot(SnapshotBuilder* snapshot_builder, | 381 Combinator combinator, |
310 RenderLayerBuilder* layer_builder, | 382 const std::vector<uint32_t>& child_node_ids, |
311 SceneDef* scene, | 383 const mojo::Size& size, |
312 NodeDef* node) { | 384 mojo::gfx::composition::BlendPtr blend) |
313 SkRect content_rect = SkRect::MakeWH(size_.width, size_.height); | 385 : NodeDef(node_id, |
314 RenderLayerBuilder children_layer_builder(&content_rect); | 386 content_transform.Pass(), |
315 if (!node->SnapshotChildren(snapshot_builder, &children_layer_builder, scene)) | 387 content_clip.Pass(), |
316 return false; | 388 combinator, |
317 | 389 child_node_ids), |
318 layer_builder->DrawSavedLayer( | 390 size_(size), |
319 children_layer_builder.Build(), content_rect, | 391 blend_(blend.Pass()) {} |
320 blend_ ? MakePaintForBlend(*blend_) : SkPaint()); | 392 |
321 return true; | 393 LayerNodeDef::~LayerNodeDef() {} |
394 | |
395 void LayerNodeDef::RecordPictureInner(const SceneContent* content, | |
396 const Snapshot* snapshot, | |
397 SkCanvas* canvas) const { | |
398 DCHECK(content); | |
399 DCHECK(snapshot); | |
400 DCHECK(canvas); | |
401 | |
402 SkPaint paint; | |
403 SetPaintForBlend(&paint, blend_.get()); | |
404 | |
405 canvas->saveLayer(SkRect::MakeWH(size_.width, size_.height), &paint); | |
406 NodeDef::RecordPictureInner(content, snapshot, canvas); | |
407 canvas->restore(); | |
322 } | 408 } |
323 | 409 |
324 } // namespace compositor | 410 } // namespace compositor |
OLD | NEW |