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

Side by Side Diff: services/gfx/compositor/graph/universe.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/universe.h ('k') | services/gfx/compositor/scene_state.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "services/gfx/compositor/graph/universe.h"
6
7 #include "base/logging.h"
8 #include "mojo/services/gfx/composition/cpp/formatting.h"
9 #include "services/gfx/compositor/graph/scene_content.h"
10
11 namespace compositor {
12
13 Universe::Universe() {}
14
15 Universe::~Universe() {}
16
17 void Universe::AddScene(const SceneLabel& label) {
18 DCHECK(scenes_.find(label.token()) == scenes_.end());
19 scenes_.emplace(label.token(),
20 std::unique_ptr<SceneInfo>(new SceneInfo(label)));
21 }
22
23 void Universe::PresentScene(const scoped_refptr<const SceneContent>& content) {
24 auto it = scenes_.find(content->label().token());
25 DCHECK(it != scenes_.end());
26 it->second->content_queue.emplace_front(content);
27 }
28
29 void Universe::RemoveScene(
30 const mojo::gfx::composition::SceneToken& scene_token) {
31 auto it = scenes_.find(scene_token.value);
32 DCHECK(it != scenes_.end());
33 scenes_.erase(it);
34 }
35
36 scoped_refptr<const Snapshot> Universe::SnapshotScene(
37 const mojo::gfx::composition::SceneToken& scene_token,
38 uint32_t version,
39 std::ostream* block_log) {
40 generation_++;
41 CHECK(generation_);
42
43 Snapshotter snapshotter(this, block_log);
44 scoped_refptr<const Snapshot> snapshot =
45 snapshotter.Build(scene_token, version);
46
47 // TODO(jeffbrown): Find a better way to prune unused scene versions.
48 // This logic is expensive and will break if there are multiple renderers
49 // involved. Perhaps we should do something like say that all renderers
50 // that live in the same universe should get snapshotted simultaneously.
51 // Or maybe we could be smarter and partition scenes by reachability
52 // using some heuristics to decide which partition should be the scene's
53 // "primary" in case of conflict (so that scenes which only appear on a
54 // single display can be rate-coupled to that display whereas those that
55 // appear in multiple places might experience some resampling).
56 // There's a similar problem lurking in the scheduler mechanism.
57 for (const auto& pair : scenes_) {
58 SceneInfo* info = pair.second.get();
59 if (info->update_generation != generation_ &&
60 info->content_queue.size() > 1) {
61 info->content_queue.erase(info->content_queue.begin() + 1,
62 info->content_queue.end());
63 }
64 }
65 return snapshot;
66 }
67
68 Universe::SceneInfo::SceneInfo(const SceneLabel& label) : label(label) {}
69
70 Universe::SceneInfo::~SceneInfo() {}
71
72 Universe::Snapshotter::Snapshotter(Universe* universe, std::ostream* block_log)
73 : SnapshotBuilder(block_log), universe_(universe) {
74 DCHECK(universe_);
75 }
76
77 Universe::Snapshotter::~Snapshotter() {
78 DCHECK(!cycle_); // must have properly unwound any cycles by now
79 }
80
81 Snapshot::Disposition Universe::Snapshotter::ResolveAndSnapshotScene(
82 const mojo::gfx::composition::SceneToken& scene_token,
83 uint32_t version,
84 scoped_refptr<const SceneContent>* out_content) {
85 auto it = universe_->scenes_.find(scene_token.value);
86 if (it == universe_->scenes_.end()) {
87 if (block_log()) {
88 *block_log() << "Scene not available: " << scene_token << std::endl;
89 }
90 return Snapshot::Disposition::kBlocked;
91 }
92
93 // TODO(jeffbrown): Ok, this logic is downright terrible. It will end
94 // up doing N^2 work when things are blocked. Replace this with some kind
95 // of sane invalidation mechanism before the system explodes.
96 SceneInfo* info = it->second.get();
97 if (info->update_generation == universe_->generation_) {
98 if (info->disposition == Snapshot::Disposition::kCycle) {
99 cycle_ = info; // start unwinding, remember where to stop
100 return Snapshot::Disposition::kCycle;
101 }
102 if (info->disposition == Snapshot::Disposition::kBlocked) {
103 if (block_log()) {
104 *block_log() << "Scene blocked (cached prior disposition): "
105 << info->label.FormattedLabel() << std::endl;
106 }
107 return Snapshot::Disposition::kBlocked;
108 }
109 } else {
110 info->update_generation = universe_->generation_;
111 if (info->content_queue.empty()) {
112 if (block_log()) {
113 *block_log() << "Scene has not presented any content: "
114 << info->label.FormattedLabel() << std::endl;
115 }
116 info->disposition = Snapshot::Disposition::kBlocked;
117 return Snapshot::Disposition::kBlocked;
118 }
119
120 auto it = info->content_queue.begin();
121 for (;;) {
122 info->disposition = Snapshot::Disposition::kCycle;
123 info->disposition = SnapshotSceneContent((*it).get());
124 if (info->disposition == Snapshot::Disposition::kSuccess)
125 break;
126 if (info->disposition == Snapshot::Disposition::kCycle) {
127 DCHECK(cycle_);
128 if (block_log()) {
129 *block_log() << "Scene is part of a cycle: "
130 << (*it)->FormattedLabel() << std::endl;
131 }
132 if (cycle_ == info)
133 cycle_ = nullptr; // found the ouroboros tail, stop unwinding
134 info->disposition = Snapshot::Disposition::kBlocked;
135 return Snapshot::Disposition::kCycle;
136 }
137 if (++it == info->content_queue.end())
138 return Snapshot::Disposition::kBlocked;
139 }
140 if (it + 1 != info->content_queue.end())
141 info->content_queue.erase(it + 1, info->content_queue.end());
142 }
143
144 DCHECK(info->disposition == Snapshot::Disposition::kSuccess);
145 DCHECK(!info->content_queue.empty());
146 const scoped_refptr<const SceneContent>& content = info->content_queue.back();
147 if (!content->MatchesVersion(version)) {
148 if (block_log()) {
149 *block_log() << "Scene version mismatch: " << info->label.FormattedLabel()
150 << ", requested version " << version
151 << ", available version " << content->version() << std::endl;
152 }
153 return Snapshot::Disposition::kBlocked;
154 }
155
156 *out_content = content;
157 return Snapshot::Disposition::kSuccess;
158 }
159
160 } // namespace compositor
OLDNEW
« no previous file with comments | « services/gfx/compositor/graph/universe.h ('k') | services/gfx/compositor/scene_state.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698