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

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

Issue 1873573003: Mozart: Ensure time always runs forward. (Closed) Base URL: git@github.com:domokit/mojo.git@moz-3
Patch Set: fix build error on Android Created 4 years, 8 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/snapshot.h ('k') | services/gfx/compositor/graph/universe.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/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/services/gfx/composition/cpp/formatting.h"
8 #include "mojo/skia/type_converters.h" 9 #include "mojo/skia/type_converters.h"
9 #include "services/gfx/compositor/graph/scene_content.h" 10 #include "services/gfx/compositor/graph/scene_content.h"
10 #include "services/gfx/compositor/graph/scene_def.h"
11 #include "services/gfx/compositor/render/render_frame.h" 11 #include "services/gfx/compositor/render/render_frame.h"
12 #include "third_party/skia/include/core/SkPictureRecorder.h" 12 #include "third_party/skia/include/core/SkPictureRecorder.h"
13 #include "third_party/skia/include/core/SkRect.h" 13 #include "third_party/skia/include/core/SkRect.h"
14 #include "third_party/skia/include/utils/SkMatrix44.h" 14 #include "third_party/skia/include/utils/SkMatrix44.h"
15 15
16 namespace compositor { 16 namespace compositor {
17 17
18 Snapshot::Snapshot() {} 18 Snapshot::Snapshot() {}
19 19
20 Snapshot::~Snapshot() {} 20 Snapshot::~Snapshot() {}
21 21
22 bool Snapshot::HasDependency(const SceneDef* scene) const { 22 bool Snapshot::HasDependency(
23 return dependencies_.find(scene->label().token()) != dependencies_.end(); 23 const mojo::gfx::composition::SceneToken& scene_token) const {
24 return dependencies_.find(scene_token.value) != dependencies_.end();
24 } 25 }
25 26
26 scoped_refptr<RenderFrame> Snapshot::CreateFrame( 27 scoped_refptr<RenderFrame> Snapshot::CreateFrame(
27 const mojo::Rect& viewport, 28 const mojo::Rect& viewport,
28 const mojo::gfx::composition::FrameInfo& frame_info) const { 29 const mojo::gfx::composition::FrameInfo& frame_info) const {
29 DCHECK(!is_blocked()); 30 DCHECK(!is_blocked());
30 DCHECK(root_scene_content_); 31 DCHECK(root_scene_content_);
31 32
32 SkIRect sk_viewport = viewport.To<SkIRect>(); 33 SkIRect sk_viewport = viewport.To<SkIRect>();
33 34
(...skipping 27 matching lines...) Expand all
61 const SceneContent* Snapshot::GetResolvedSceneContent( 62 const SceneContent* Snapshot::GetResolvedSceneContent(
62 const SceneNode* scene_node) const { 63 const SceneNode* scene_node) const {
63 DCHECK(!is_blocked()); 64 DCHECK(!is_blocked());
64 65
65 auto it = resolved_scene_contents_.find(scene_node); 66 auto it = resolved_scene_contents_.find(scene_node);
66 DCHECK(it != resolved_scene_contents_.end()); 67 DCHECK(it != resolved_scene_contents_.end());
67 return it->second.get(); 68 return it->second.get();
68 } 69 }
69 70
70 SnapshotBuilder::SnapshotBuilder(std::ostream* block_log) 71 SnapshotBuilder::SnapshotBuilder(std::ostream* block_log)
71 : block_log_(block_log), snapshot_(new Snapshot()) {} 72 : snapshot_(new Snapshot()), block_log_(block_log) {}
72 73
73 SnapshotBuilder::~SnapshotBuilder() {} 74 SnapshotBuilder::~SnapshotBuilder() {}
74 75
75 Snapshot::Disposition SnapshotBuilder::SnapshotNode( 76 Snapshot::Disposition SnapshotBuilder::SnapshotNode(
76 const Node* node, 77 const Node* node,
77 const SceneContent* content) { 78 const SceneContent* content) {
78 DCHECK(snapshot_); 79 DCHECK(snapshot_);
79 DCHECK(node); 80 DCHECK(node);
80 DCHECK(content); 81 DCHECK(content);
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::SnapshotReferencedScene(
93 const Node* node,
94 const SceneContent* content) {
95 DCHECK(snapshot_);
96 DCHECK(node);
97 DCHECK(content);
98 DCHECK(node == content->GetRootNodeIfExists());
99
100 auto storage = snapshot_->node_dispositions_.emplace(
101 node, Snapshot::Disposition::kCycle);
102 if (!storage.second) {
103 if (storage.first->second == Snapshot::Disposition::kCycle)
104 cycle_ = content; // start unwinding, remember where to stop
105 return storage.first->second;
106 }
107
108 Snapshot::Disposition disposition = node->RecordSnapshot(content, this);
109 if (disposition == Snapshot::Disposition::kSuccess) {
110 snapshot_->node_dispositions_[node] = disposition;
111 return disposition;
112 }
113
114 // We cannot reuse the iterator in |storage.first| because it may have
115 // been invalidated by the call to |RecordSnapshot| due to rehashing so
116 // we must look up the node again just in case.
117 snapshot_->node_dispositions_[node] = Snapshot::Disposition::kBlocked;
118
119 if (disposition == Snapshot::Disposition::kCycle) {
120 DCHECK(cycle_);
121 if (block_log_) {
122 *block_log_ << "Scene blocked because it is part of a cycle: "
123 << content->FormattedLabel() << std::endl;
124 }
125 if (cycle_ == content) {
126 cycle_ = nullptr; // found the ouroboros tail, stop unwinding
127 disposition = Snapshot::Disposition::kBlocked;
128 }
129 }
130 return disposition;
131 }
132 Snapshot::Disposition SnapshotBuilder::SnapshotScene(
133 const SceneDef* scene,
134 uint32_t version,
135 const SceneNode* referrer_node, 93 const SceneNode* referrer_node,
136 const SceneContent* referrer_content) { 94 const SceneContent* referrer_content) {
137 DCHECK(snapshot_); 95 DCHECK(snapshot_);
138 DCHECK(scene);
139 DCHECK(referrer_node); 96 DCHECK(referrer_node);
140 DCHECK(referrer_content); 97 DCHECK(referrer_content);
141 98
142 // This function should only ever be called once when snapshotting the 99 // This function should only ever be called once when snapshotting the
143 // referring |SceneNode| at which point the result will be memoized 100 // referring |SceneNode| at which point the result will be memoized
144 // by |SnapshotNode| as usual so reentrance should not occur. 101 // by |SnapshotNode| as usual so reentrance should not occur.
145 DCHECK(snapshot_->resolved_scene_contents_.find(referrer_node) == 102 DCHECK(snapshot_->resolved_scene_contents_.find(referrer_node) ==
146 snapshot_->resolved_scene_contents_.end()); 103 snapshot_->resolved_scene_contents_.end());
147 104
148 snapshot_->dependencies_.insert(scene->label().token()); 105 auto scene_resource =
106 static_cast<const SceneResource*>(referrer_content->GetResource(
107 referrer_node->scene_resource_id(), Resource::Type::kScene));
108 DCHECK(scene_resource);
149 109
150 const SceneContent* content = scene->FindContent(version); 110 scoped_refptr<const SceneContent> content;
151 if (!content) { 111 Snapshot::Disposition disposition = AddDependencyResolveAndSnapshotScene(
112 scene_resource->scene_token(), referrer_node->scene_version(), &content);
113
114 if (disposition == Snapshot::Disposition::kSuccess) {
115 snapshot_->resolved_scene_contents_[referrer_node] = content;
116 } else if (disposition == Snapshot::Disposition::kBlocked) {
152 if (block_log_) { 117 if (block_log_) {
153 *block_log_ << "Scene node blocked because its referenced scene is not " 118 *block_log_ << "Scene node's referenced scene is blocked: "
154 "available with the requested version: "
155 << referrer_node->FormattedLabel(referrer_content) 119 << referrer_node->FormattedLabel(referrer_content)
156 << ", scene " << scene->label().FormattedLabel() 120 << ", referenced scene " << scene_resource->scene_token()
157 << ", requested version " << version << ", current version " 121 << ", version " << referrer_node->scene_version()
158 << scene->version() << std::endl; 122 << std::endl;
123 }
124 }
125 return disposition;
126 }
127
128 Snapshot::Disposition SnapshotBuilder::SnapshotSceneContent(
129 const SceneContent* content) {
130 DCHECK(snapshot_);
131 DCHECK(content);
132
133 const Node* root = content->GetRootNodeIfExists();
134 if (!root) {
135 if (block_log_) {
136 *block_log_ << "Scene has no root node: " << content->FormattedLabel()
137 << std::endl;
159 } 138 }
160 return Snapshot::Disposition::kBlocked; 139 return Snapshot::Disposition::kBlocked;
161 } 140 }
162 141
163 const Node* root = content->GetRootNodeIfExists(); 142 return SnapshotNode(root, content);
164 if (!root) {
165 if (block_log_) {
166 *block_log_ << "Scene node blocked because its referenced scene has no "
167 "root node: "
168 << referrer_node->FormattedLabel(referrer_content)
169 << ", scene " << content->FormattedLabel() << std::endl;
170 }
171 return Snapshot::Disposition::kBlocked;
172 }
173
174 snapshot_->resolved_scene_contents_[referrer_node] = content;
175 return SnapshotRootAndDetectCycles(root, content);
176 } 143 }
177 144
178 Snapshot::Disposition SnapshotBuilder::SnapshotRenderer(const SceneDef* scene) { 145 Snapshot::Disposition SnapshotBuilder::AddDependencyResolveAndSnapshotScene(
179 DCHECK(!snapshot_->root_scene_content_); 146 const mojo::gfx::composition::SceneToken& scene_token,
147 uint32_t version,
148 scoped_refptr<const SceneContent>* out_content) {
149 DCHECK(out_content);
180 150
181 snapshot_->dependencies_.insert(scene->label().token()); 151 snapshot_->dependencies_.insert(scene_token.value);
182 152 return ResolveAndSnapshotScene(scene_token, version, out_content);
183 const SceneContent* content =
184 scene->FindContent(mojo::gfx::composition::kSceneVersionNone);
185 if (!content) {
186 if (block_log_) {
187 *block_log_ << "Rendering blocked because the root scene has no content: "
188 << scene->label().FormattedLabel() << std::endl;
189 }
190 return Snapshot::Disposition::kBlocked;
191 }
192
193 const Node* root = content->GetRootNodeIfExists();
194 if (!root) {
195 if (block_log_) {
196 *block_log_ << "Rendering blocked the root scene has no root node: "
197 << content->FormattedLabel() << std::endl;
198 }
199 return Snapshot::Disposition::kBlocked;
200 }
201
202 snapshot_->root_scene_content_ = content;
203 return SnapshotRootAndDetectCycles(root, content);
204 } 153 }
205 154
206 scoped_refptr<const Snapshot> SnapshotBuilder::Build( 155 scoped_refptr<const Snapshot> SnapshotBuilder::Build(
207 const SceneDef* root_scene) { 156 const mojo::gfx::composition::SceneToken& scene_token,
157 uint32_t version) {
208 DCHECK(snapshot_); 158 DCHECK(snapshot_);
209 DCHECK(root_scene); 159 DCHECK(!snapshot_->root_scene_content_);
210 160
211 snapshot_->disposition_ = SnapshotRenderer(root_scene); 161 scoped_refptr<const SceneContent> content;
212 DCHECK(!cycle_); // must have properly unwound any cycles by now 162 snapshot_->disposition_ =
163 AddDependencyResolveAndSnapshotScene(scene_token, version, &content);
213 164
214 if (snapshot_->is_blocked()) { 165 if (!snapshot_->is_blocked()) {
215 snapshot_->root_scene_content_ = nullptr; 166 snapshot_->root_scene_content_ = content;
167 } else {
216 snapshot_->resolved_scene_contents_.clear(); 168 snapshot_->resolved_scene_contents_.clear();
217 snapshot_->node_dispositions_.clear(); 169 snapshot_->node_dispositions_.clear();
218 } 170 }
219 return std::move(snapshot_); 171 return std::move(snapshot_);
220 } 172 }
221 173
222 } // namespace compositor 174 } // namespace compositor
OLDNEW
« no previous file with comments | « services/gfx/compositor/graph/snapshot.h ('k') | services/gfx/compositor/graph/universe.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698