Chromium Code Reviews| 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 |