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, |
| 219 [this, content, snapshot, canvas](const NodeDef* child_node) -> bool { |
| 220 child_node->RecordPicture(content, snapshot, canvas); |
146 return true; | 221 return true; |
147 for (NodeDef* child_node : child_nodes_) { | 222 }); |
148 RenderLayerBuilder child_layer_builder; | 223 } |
149 if (child_node->Snapshot(snapshot_builder, &child_layer_builder, | 224 |
150 scene)) { | 225 RectNodeDef::RectNodeDef(uint32_t node_id, |
151 layer_builder->DrawLayer(child_layer_builder.Build()); | 226 mojo::TransformPtr content_transform, |
152 return true; | 227 mojo::RectPtr content_clip, |
153 } | 228 Combinator combinator, |
154 } | 229 const std::vector<uint32_t>& child_node_ids, |
155 if (snapshot_builder->block_log()) { | 230 const mojo::Rect& content_rect, |
156 *snapshot_builder->block_log() | 231 const mojo::gfx::composition::Color& color) |
157 << "Node with FALLBACK combinator blocked since " | 232 : NodeDef(node_id, |
158 "all of its children are blocked: " | 233 content_transform.Pass(), |
159 << FormattedLabel(scene) << std::endl; | 234 content_clip.Pass(), |
160 } | 235 combinator, |
161 return false; // blocked | 236 child_node_ids), |
162 } | 237 content_rect_(content_rect), |
163 | 238 color_(color) {} |
164 default: { | 239 |
165 if (snapshot_builder->block_log()) { | 240 RectNodeDef::~RectNodeDef() {} |
166 *snapshot_builder->block_log() | 241 |
167 << "Unrecognized combinator: " << FormattedLabel(scene) | 242 void RectNodeDef::RecordPictureInner(const SceneContent* content, |
168 << std::endl; | 243 const Snapshot* snapshot, |
169 } | 244 SkCanvas* canvas) const { |
170 return false; | 245 DCHECK(content); |
171 } | 246 DCHECK(snapshot); |
172 } | 247 DCHECK(canvas); |
173 } | 248 |
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; | 249 SkPaint paint; |
195 paint.setColor(MakeSkColor(color_)); | 250 paint.setColor(MakeSkColor(color_)); |
196 layer_builder->DrawRect(content_rect_.To<SkRect>(), paint); | 251 canvas->drawRect(content_rect_.To<SkRect>(), paint); |
197 | 252 |
198 return node->SnapshotChildren(snapshot_builder, layer_builder, scene); | 253 NodeDef::RecordPictureInner(content, snapshot, canvas); |
199 } | 254 } |
200 | 255 |
201 ImageNodeOp::ImageNodeOp(const mojo::Rect& content_rect, | 256 ImageNodeDef::ImageNodeDef(uint32_t node_id, |
202 mojo::RectPtr image_rect, | 257 mojo::TransformPtr content_transform, |
203 uint32 image_resource_id, | 258 mojo::RectPtr content_clip, |
204 mojo::gfx::composition::BlendPtr blend) | 259 Combinator combinator, |
205 : content_rect_(content_rect), | 260 const std::vector<uint32_t>& child_node_ids, |
| 261 const mojo::Rect& content_rect, |
| 262 mojo::RectPtr image_rect, |
| 263 uint32 image_resource_id, |
| 264 mojo::gfx::composition::BlendPtr blend) |
| 265 : NodeDef(node_id, |
| 266 content_transform.Pass(), |
| 267 content_clip.Pass(), |
| 268 combinator, |
| 269 child_node_ids), |
| 270 content_rect_(content_rect), |
206 image_rect_(image_rect.Pass()), | 271 image_rect_(image_rect.Pass()), |
207 image_resource_id_(image_resource_id), | 272 image_resource_id_(image_resource_id), |
208 blend_(blend.Pass()) {} | 273 blend_(blend.Pass()) {} |
209 | 274 |
210 ImageNodeOp::~ImageNodeOp() {} | 275 ImageNodeDef::~ImageNodeDef() {} |
211 | 276 |
212 bool ImageNodeOp::Validate(SceneDef* scene, NodeDef* node, std::ostream& err) { | 277 bool ImageNodeDef::RecordContent(SceneContentBuilder* builder) const { |
213 image_resource_ = scene->FindImageResource(image_resource_id_); | 278 DCHECK(builder); |
214 if (!image_resource_) { | 279 |
215 err << "Node refers to unknown or invalid image resource: " | 280 return NodeDef::RecordContent(builder) && |
216 << node->FormattedLabel(scene) | 281 builder->RequireResource(image_resource_id_, ResourceDef::Type::kImage, |
217 << ", image_resource_id=" << image_resource_id_; | 282 node_id()); |
218 return false; | 283 } |
219 } | 284 |
220 return true; | 285 void ImageNodeDef::RecordPictureInner(const SceneContent* content, |
221 } | 286 const Snapshot* snapshot, |
222 | 287 SkCanvas* canvas) const { |
223 bool ImageNodeOp::Snapshot(SnapshotBuilder* snapshot_builder, | 288 DCHECK(content); |
224 RenderLayerBuilder* layer_builder, | 289 DCHECK(snapshot); |
225 SceneDef* scene, | 290 DCHECK(canvas); |
226 NodeDef* node) { | 291 |
227 DCHECK(image_resource_); | 292 auto image_resource = static_cast<const ImageResourceDef*>( |
228 | 293 content->GetResource(image_resource_id_, ResourceDef::Type::kImage)); |
229 if (!image_resource_->image()) { | 294 DCHECK(image_resource); |
230 if (snapshot_builder->block_log()) { | 295 |
231 *snapshot_builder->block_log() | 296 SkPaint paint; |
232 << "Node blocked due to its referenced image " | 297 SetPaintForBlend(&paint, blend_.get()); |
233 "resource being unavailable: " | 298 |
234 << node->FormattedLabel(scene) << std::endl; | 299 canvas->drawImageRect(image_resource->image()->image().get(), |
235 } | 300 image_rect_ |
236 return false; | 301 ? image_rect_->To<SkRect>() |
237 } | 302 : SkRect::MakeWH(image_resource->image()->width(), |
238 | 303 image_resource->image()->height()), |
239 layer_builder->DrawImage( | 304 content_rect_.To<SkRect>(), &paint); |
240 image_resource_->image(), content_rect_.To<SkRect>(), | 305 |
241 image_rect_ ? image_rect_->To<SkRect>() | 306 NodeDef::RecordPictureInner(content, snapshot, canvas); |
242 : SkRect::MakeWH(image_resource_->image()->width(), | 307 } |
243 image_resource_->image()->height()), | 308 |
244 blend_ ? MakePaintForBlend(*blend_) : SkPaint()); | 309 SceneNodeDef::SceneNodeDef(uint32_t node_id, |
245 | 310 mojo::TransformPtr content_transform, |
246 return node->SnapshotChildren(snapshot_builder, layer_builder, scene); | 311 mojo::RectPtr content_clip, |
247 } | 312 Combinator combinator, |
248 | 313 const std::vector<uint32_t>& child_node_ids, |
249 SceneNodeOp::SceneNodeOp(uint32_t scene_resource_id, uint32_t scene_version) | 314 uint32_t scene_resource_id, |
250 : scene_resource_id_(scene_resource_id), scene_version_(scene_version) {} | 315 uint32_t scene_version) |
251 | 316 : NodeDef(node_id, |
252 SceneNodeOp::~SceneNodeOp() {} | 317 content_transform.Pass(), |
253 | 318 content_clip.Pass(), |
254 bool SceneNodeOp::Validate(SceneDef* scene, NodeDef* node, std::ostream& err) { | 319 combinator, |
255 scene_resource_ = scene->FindSceneResource(scene_resource_id_); | 320 child_node_ids), |
256 if (!scene_resource_) { | 321 scene_resource_id_(scene_resource_id), |
257 err << "Node refers to unknown or invalid scene resource: " | 322 scene_version_(scene_version) {} |
258 << node->FormattedLabel(scene) | 323 |
259 << ", scene_resource_id=" << scene_resource_id_; | 324 SceneNodeDef::~SceneNodeDef() {} |
260 return false; | 325 |
261 } | 326 bool SceneNodeDef::RecordContent(SceneContentBuilder* builder) const { |
262 return true; | 327 DCHECK(builder); |
263 } | 328 |
264 | 329 return NodeDef::RecordContent(builder) && |
265 bool SceneNodeOp::Snapshot(SnapshotBuilder* snapshot_builder, | 330 builder->RequireResource(scene_resource_id_, ResourceDef::Type::kScene, |
266 RenderLayerBuilder* layer_builder, | 331 node_id()); |
267 SceneDef* scene, | 332 } |
268 NodeDef* node) { | 333 |
269 DCHECK(scene_resource_); | 334 Snapshot::Disposition SceneNodeDef::RecordSnapshot( |
270 | 335 const SceneContent* content, |
271 SceneDef* referenced_scene = scene_resource_->referenced_scene(); | 336 SnapshotBuilder* builder) const { |
| 337 DCHECK(content); |
| 338 DCHECK(builder); |
| 339 |
| 340 auto scene_resource = static_cast<const SceneResourceDef*>( |
| 341 content->GetResource(scene_resource_id_, ResourceDef::Type::kScene)); |
| 342 DCHECK(scene_resource); |
| 343 |
| 344 SceneDef* referenced_scene = scene_resource->referenced_scene().get(); |
272 if (!referenced_scene) { | 345 if (!referenced_scene) { |
273 if (snapshot_builder->block_log()) { | 346 if (builder->block_log()) { |
274 *snapshot_builder->block_log() | 347 *builder->block_log() |
275 << "Node blocked due to its referenced scene " | 348 << "Scene node blocked because its referenced scene is unavailable: " |
276 "resource being unavailable: " | 349 << FormattedLabel(content) << std::endl; |
277 << node->FormattedLabel(scene) << std::endl; | 350 } |
278 } | 351 return Snapshot::Disposition::kBlocked; |
279 return false; | 352 } |
280 } | 353 |
281 | 354 Snapshot::Disposition disposition = |
282 uint32_t actual_version = referenced_scene->version(); | 355 builder->SnapshotScene(referenced_scene, scene_version_, this, content); |
283 if (scene_version_ != mojo::gfx::composition::kSceneVersionNone && | 356 if (disposition != Snapshot::Disposition::kSuccess) |
284 actual_version != mojo::gfx::composition::kSceneVersionNone && | 357 return disposition; |
285 scene_version_ != actual_version) { | 358 return NodeDef::RecordSnapshot(content, builder); |
286 if (snapshot_builder->block_log()) { | 359 } |
287 *snapshot_builder->block_log() | 360 |
288 << "Node blocked due to its referenced scene " | 361 void SceneNodeDef::RecordPictureInner(const SceneContent* content, |
289 "resource not having the desired version: " | 362 const Snapshot* snapshot, |
290 << node->FormattedLabel(scene) | 363 SkCanvas* canvas) const { |
291 << ", requested_version=" << scene_version_ | 364 DCHECK(content); |
292 << ", actual_version=" << actual_version << std::endl; | 365 DCHECK(snapshot); |
293 } | 366 DCHECK(canvas); |
294 return false; | 367 |
295 } | 368 const SceneContent* resolved_content = |
296 | 369 snapshot->GetResolvedSceneContent(this); |
297 if (!referenced_scene->Snapshot(snapshot_builder, layer_builder)) | 370 DCHECK(resolved_content); |
298 return false; | 371 |
299 | 372 const NodeDef* root_node = resolved_content->GetRootNodeIfExists(); |
300 return node->SnapshotChildren(snapshot_builder, layer_builder, scene); | 373 DCHECK(root_node); // must have a root otherwise would have been blocked |
301 } | 374 root_node->RecordPicture(resolved_content, snapshot, canvas); |
302 | 375 |
303 LayerNodeOp::LayerNodeOp(const mojo::Size& size, | 376 NodeDef::RecordPictureInner(content, snapshot, canvas); |
304 mojo::gfx::composition::BlendPtr blend) | 377 } |
305 : size_(size), blend_(blend.Pass()) {} | 378 |
306 | 379 LayerNodeDef::LayerNodeDef(uint32_t node_id, |
307 LayerNodeOp::~LayerNodeOp() {} | 380 mojo::TransformPtr content_transform, |
308 | 381 mojo::RectPtr content_clip, |
309 bool LayerNodeOp::Snapshot(SnapshotBuilder* snapshot_builder, | 382 Combinator combinator, |
310 RenderLayerBuilder* layer_builder, | 383 const std::vector<uint32_t>& child_node_ids, |
311 SceneDef* scene, | 384 const mojo::Size& size, |
312 NodeDef* node) { | 385 mojo::gfx::composition::BlendPtr blend) |
313 SkRect content_rect = SkRect::MakeWH(size_.width, size_.height); | 386 : NodeDef(node_id, |
314 RenderLayerBuilder children_layer_builder(&content_rect); | 387 content_transform.Pass(), |
315 if (!node->SnapshotChildren(snapshot_builder, &children_layer_builder, scene)) | 388 content_clip.Pass(), |
316 return false; | 389 combinator, |
317 | 390 child_node_ids), |
318 layer_builder->DrawSavedLayer( | 391 size_(size), |
319 children_layer_builder.Build(), content_rect, | 392 blend_(blend.Pass()) {} |
320 blend_ ? MakePaintForBlend(*blend_) : SkPaint()); | 393 |
321 return true; | 394 LayerNodeDef::~LayerNodeDef() {} |
| 395 |
| 396 void LayerNodeDef::RecordPictureInner(const SceneContent* content, |
| 397 const Snapshot* snapshot, |
| 398 SkCanvas* canvas) const { |
| 399 DCHECK(content); |
| 400 DCHECK(snapshot); |
| 401 DCHECK(canvas); |
| 402 |
| 403 SkPaint paint; |
| 404 SetPaintForBlend(&paint, blend_.get()); |
| 405 |
| 406 canvas->saveLayer(SkRect::MakeWH(size_.width, size_.height), &paint); |
| 407 NodeDef::RecordPictureInner(content, snapshot, canvas); |
| 408 canvas->restore(); |
322 } | 409 } |
323 | 410 |
324 } // namespace compositor | 411 } // namespace compositor |
OLD | NEW |