| 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/snapshot.h" | 5 #include "services/gfx/compositor/graph/snapshot.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "mojo/skia/type_converters.h" | 8 #include "mojo/skia/type_converters.h" |
| 9 #include "services/gfx/compositor/graph/scene_content.h" | 9 #include "services/gfx/compositor/graph/scene_content.h" |
| 10 #include "services/gfx/compositor/graph/scene_def.h" | 10 #include "services/gfx/compositor/graph/scene_def.h" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 void Snapshot::HitTest(const mojo::PointF& point, | 41 void Snapshot::HitTest(const mojo::PointF& point, |
| 42 mojo::gfx::composition::HitTestResult* result) const { | 42 mojo::gfx::composition::HitTestResult* result) const { |
| 43 DCHECK(result); | 43 DCHECK(result); |
| 44 DCHECK(!is_blocked()); | 44 DCHECK(!is_blocked()); |
| 45 DCHECK(root_scene_content_); | 45 DCHECK(root_scene_content_); |
| 46 | 46 |
| 47 root_scene_content_->HitTest(this, point.To<SkPoint>(), SkMatrix44::I(), | 47 root_scene_content_->HitTest(this, point.To<SkPoint>(), SkMatrix44::I(), |
| 48 &result->root); | 48 &result->root); |
| 49 } | 49 } |
| 50 | 50 |
| 51 bool Snapshot::IsNodeBlocked(const NodeDef* node) const { | 51 bool Snapshot::IsNodeBlocked(const Node* node) const { |
| 52 DCHECK(!is_blocked()); | 52 DCHECK(!is_blocked()); |
| 53 | 53 |
| 54 auto it = node_dispositions_.find(node); | 54 auto it = node_dispositions_.find(node); |
| 55 DCHECK(it != node_dispositions_.end()); | 55 DCHECK(it != node_dispositions_.end()); |
| 56 DCHECK(it->second == Disposition::kSuccess || | 56 DCHECK(it->second == Disposition::kSuccess || |
| 57 it->second == Disposition::kBlocked); | 57 it->second == Disposition::kBlocked); |
| 58 return it->second == Disposition::kBlocked; | 58 return it->second == Disposition::kBlocked; |
| 59 } | 59 } |
| 60 | 60 |
| 61 const SceneContent* Snapshot::GetResolvedSceneContent( | 61 const SceneContent* Snapshot::GetResolvedSceneContent( |
| 62 const SceneNodeDef* scene_node) const { | 62 const SceneNode* scene_node) const { |
| 63 DCHECK(!is_blocked()); | 63 DCHECK(!is_blocked()); |
| 64 | 64 |
| 65 auto it = resolved_scene_contents_.find(scene_node); | 65 auto it = resolved_scene_contents_.find(scene_node); |
| 66 DCHECK(it != resolved_scene_contents_.end()); | 66 DCHECK(it != resolved_scene_contents_.end()); |
| 67 return it->second.get(); | 67 return it->second.get(); |
| 68 } | 68 } |
| 69 | 69 |
| 70 SnapshotBuilder::SnapshotBuilder(std::ostream* block_log) | 70 SnapshotBuilder::SnapshotBuilder(std::ostream* block_log) |
| 71 : block_log_(block_log), snapshot_(new Snapshot()) {} | 71 : block_log_(block_log), snapshot_(new Snapshot()) {} |
| 72 | 72 |
| 73 SnapshotBuilder::~SnapshotBuilder() {} | 73 SnapshotBuilder::~SnapshotBuilder() {} |
| 74 | 74 |
| 75 Snapshot::Disposition SnapshotBuilder::SnapshotNode( | 75 Snapshot::Disposition SnapshotBuilder::SnapshotNode( |
| 76 const NodeDef* node, | 76 const Node* node, |
| 77 const SceneContent* content) { | 77 const SceneContent* content) { |
| 78 DCHECK(snapshot_); | 78 DCHECK(snapshot_); |
| 79 DCHECK(node); | 79 DCHECK(node); |
| 80 DCHECK(content); | 80 DCHECK(content); |
| 81 DCHECK(node != content->GetRootNodeIfExists()); | 81 DCHECK(node != content->GetRootNodeIfExists()); |
| 82 | 82 |
| 83 auto it = snapshot_->node_dispositions_.find(node); | 83 auto it = snapshot_->node_dispositions_.find(node); |
| 84 if (it != snapshot_->node_dispositions_.end()) | 84 if (it != snapshot_->node_dispositions_.end()) |
| 85 return it->second; | 85 return it->second; |
| 86 | 86 |
| 87 Snapshot::Disposition disposition = node->RecordSnapshot(content, this); | 87 Snapshot::Disposition disposition = node->RecordSnapshot(content, this); |
| 88 snapshot_->node_dispositions_[node] = disposition; | 88 snapshot_->node_dispositions_[node] = disposition; |
| 89 return disposition; | 89 return disposition; |
| 90 } | 90 } |
| 91 | 91 |
| 92 Snapshot::Disposition SnapshotBuilder::SnapshotRootAndDetectCycles( | 92 Snapshot::Disposition SnapshotBuilder::SnapshotRootAndDetectCycles( |
| 93 const NodeDef* node, | 93 const Node* node, |
| 94 const SceneContent* content) { | 94 const SceneContent* content) { |
| 95 DCHECK(snapshot_); | 95 DCHECK(snapshot_); |
| 96 DCHECK(node); | 96 DCHECK(node); |
| 97 DCHECK(content); | 97 DCHECK(content); |
| 98 DCHECK(node == content->GetRootNodeIfExists()); | 98 DCHECK(node == content->GetRootNodeIfExists()); |
| 99 | 99 |
| 100 auto storage = snapshot_->node_dispositions_.emplace( | 100 auto storage = snapshot_->node_dispositions_.emplace( |
| 101 node, Snapshot::Disposition::kCycle); | 101 node, Snapshot::Disposition::kCycle); |
| 102 if (!storage.second) { | 102 if (!storage.second) { |
| 103 if (storage.first->second == Snapshot::Disposition::kCycle) | 103 if (storage.first->second == Snapshot::Disposition::kCycle) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 125 if (cycle_ == content) { | 125 if (cycle_ == content) { |
| 126 cycle_ = nullptr; // found the ouroboros tail, stop unwinding | 126 cycle_ = nullptr; // found the ouroboros tail, stop unwinding |
| 127 disposition = Snapshot::Disposition::kBlocked; | 127 disposition = Snapshot::Disposition::kBlocked; |
| 128 } | 128 } |
| 129 } | 129 } |
| 130 return disposition; | 130 return disposition; |
| 131 } | 131 } |
| 132 Snapshot::Disposition SnapshotBuilder::SnapshotScene( | 132 Snapshot::Disposition SnapshotBuilder::SnapshotScene( |
| 133 const SceneDef* scene, | 133 const SceneDef* scene, |
| 134 uint32_t version, | 134 uint32_t version, |
| 135 const SceneNodeDef* referrer_node, | 135 const SceneNode* referrer_node, |
| 136 const SceneContent* referrer_content) { | 136 const SceneContent* referrer_content) { |
| 137 DCHECK(snapshot_); | 137 DCHECK(snapshot_); |
| 138 DCHECK(scene); | 138 DCHECK(scene); |
| 139 DCHECK(referrer_node); | 139 DCHECK(referrer_node); |
| 140 DCHECK(referrer_content); | 140 DCHECK(referrer_content); |
| 141 | 141 |
| 142 // This function should only ever be called once when snapshotting the | 142 // This function should only ever be called once when snapshotting the |
| 143 // referring |SceneNodeDef| at which point the result will be memoized | 143 // referring |SceneNode| at which point the result will be memoized |
| 144 // by |SnapshotNode| as usual so reentrance should not occur. | 144 // by |SnapshotNode| as usual so reentrance should not occur. |
| 145 DCHECK(snapshot_->resolved_scene_contents_.find(referrer_node) == | 145 DCHECK(snapshot_->resolved_scene_contents_.find(referrer_node) == |
| 146 snapshot_->resolved_scene_contents_.end()); | 146 snapshot_->resolved_scene_contents_.end()); |
| 147 | 147 |
| 148 snapshot_->dependencies_.insert(scene->label().token()); | 148 snapshot_->dependencies_.insert(scene->label().token()); |
| 149 | 149 |
| 150 const SceneContent* content = scene->FindContent(version); | 150 const SceneContent* content = scene->FindContent(version); |
| 151 if (!content) { | 151 if (!content) { |
| 152 if (block_log_) { | 152 if (block_log_) { |
| 153 *block_log_ << "Scene node blocked because its referenced scene is not " | 153 *block_log_ << "Scene node blocked because its referenced scene is not " |
| 154 "available with the requested version: " | 154 "available with the requested version: " |
| 155 << referrer_node->FormattedLabel(referrer_content) | 155 << referrer_node->FormattedLabel(referrer_content) |
| 156 << ", scene " << scene->label().FormattedLabel() | 156 << ", scene " << scene->label().FormattedLabel() |
| 157 << ", requested version " << version << ", current version " | 157 << ", requested version " << version << ", current version " |
| 158 << scene->version() << std::endl; | 158 << scene->version() << std::endl; |
| 159 } | 159 } |
| 160 return Snapshot::Disposition::kBlocked; | 160 return Snapshot::Disposition::kBlocked; |
| 161 } | 161 } |
| 162 | 162 |
| 163 const NodeDef* root = content->GetRootNodeIfExists(); | 163 const Node* root = content->GetRootNodeIfExists(); |
| 164 if (!root) { | 164 if (!root) { |
| 165 if (block_log_) { | 165 if (block_log_) { |
| 166 *block_log_ << "Scene node blocked because its referenced scene has no " | 166 *block_log_ << "Scene node blocked because its referenced scene has no " |
| 167 "root node: " | 167 "root node: " |
| 168 << referrer_node->FormattedLabel(referrer_content) | 168 << referrer_node->FormattedLabel(referrer_content) |
| 169 << ", scene " << content->FormattedLabel() << std::endl; | 169 << ", scene " << content->FormattedLabel() << std::endl; |
| 170 } | 170 } |
| 171 return Snapshot::Disposition::kBlocked; | 171 return Snapshot::Disposition::kBlocked; |
| 172 } | 172 } |
| 173 | 173 |
| 174 snapshot_->resolved_scene_contents_[referrer_node] = content; | 174 snapshot_->resolved_scene_contents_[referrer_node] = content; |
| 175 return SnapshotRootAndDetectCycles(root, content); | 175 return SnapshotRootAndDetectCycles(root, content); |
| 176 } | 176 } |
| 177 | 177 |
| 178 Snapshot::Disposition SnapshotBuilder::SnapshotRenderer(const SceneDef* scene) { | 178 Snapshot::Disposition SnapshotBuilder::SnapshotRenderer(const SceneDef* scene) { |
| 179 DCHECK(!snapshot_->root_scene_content_); | 179 DCHECK(!snapshot_->root_scene_content_); |
| 180 | 180 |
| 181 snapshot_->dependencies_.insert(scene->label().token()); | 181 snapshot_->dependencies_.insert(scene->label().token()); |
| 182 | 182 |
| 183 const SceneContent* content = | 183 const SceneContent* content = |
| 184 scene->FindContent(mojo::gfx::composition::kSceneVersionNone); | 184 scene->FindContent(mojo::gfx::composition::kSceneVersionNone); |
| 185 if (!content) { | 185 if (!content) { |
| 186 if (block_log_) { | 186 if (block_log_) { |
| 187 *block_log_ << "Rendering blocked because the root scene has no content: " | 187 *block_log_ << "Rendering blocked because the root scene has no content: " |
| 188 << scene->label().FormattedLabel() << std::endl; | 188 << scene->label().FormattedLabel() << std::endl; |
| 189 } | 189 } |
| 190 return Snapshot::Disposition::kBlocked; | 190 return Snapshot::Disposition::kBlocked; |
| 191 } | 191 } |
| 192 | 192 |
| 193 const NodeDef* root = content->GetRootNodeIfExists(); | 193 const Node* root = content->GetRootNodeIfExists(); |
| 194 if (!root) { | 194 if (!root) { |
| 195 if (block_log_) { | 195 if (block_log_) { |
| 196 *block_log_ << "Rendering blocked the root scene has no root node: " | 196 *block_log_ << "Rendering blocked the root scene has no root node: " |
| 197 << content->FormattedLabel() << std::endl; | 197 << content->FormattedLabel() << std::endl; |
| 198 } | 198 } |
| 199 return Snapshot::Disposition::kBlocked; | 199 return Snapshot::Disposition::kBlocked; |
| 200 } | 200 } |
| 201 | 201 |
| 202 snapshot_->root_scene_content_ = content; | 202 snapshot_->root_scene_content_ = content; |
| 203 return SnapshotRootAndDetectCycles(root, content); | 203 return SnapshotRootAndDetectCycles(root, content); |
| 204 } | 204 } |
| 205 | 205 |
| 206 scoped_refptr<const Snapshot> SnapshotBuilder::Build( | 206 scoped_refptr<const Snapshot> SnapshotBuilder::Build( |
| 207 const SceneDef* root_scene) { | 207 const SceneDef* root_scene) { |
| 208 DCHECK(snapshot_); | 208 DCHECK(snapshot_); |
| 209 DCHECK(root_scene); | 209 DCHECK(root_scene); |
| 210 | 210 |
| 211 snapshot_->disposition_ = SnapshotRenderer(root_scene); | 211 snapshot_->disposition_ = SnapshotRenderer(root_scene); |
| 212 DCHECK(!cycle_); // must have properly unwound any cycles by now | 212 DCHECK(!cycle_); // must have properly unwound any cycles by now |
| 213 | 213 |
| 214 if (snapshot_->is_blocked()) { | 214 if (snapshot_->is_blocked()) { |
| 215 snapshot_->root_scene_content_ = nullptr; | 215 snapshot_->root_scene_content_ = nullptr; |
| 216 snapshot_->resolved_scene_contents_.clear(); | 216 snapshot_->resolved_scene_contents_.clear(); |
| 217 snapshot_->node_dispositions_.clear(); | 217 snapshot_->node_dispositions_.clear(); |
| 218 } | 218 } |
| 219 return std::move(snapshot_); | 219 return std::move(snapshot_); |
| 220 } | 220 } |
| 221 | 221 |
| 222 } // namespace compositor | 222 } // namespace compositor |
| OLD | NEW |