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

Side by Side Diff: services/ui/ws/frame_generator.cc

Issue 2489003002: Convert mustash use surface references. (Closed)
Patch Set: Created 4 years, 1 month 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 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/ui/ws/frame_generator.h" 5 #include "services/ui/ws/frame_generator.h"
6 6
7 #include "base/containers/adapters.h" 7 #include "base/containers/adapters.h"
8 #include "cc/output/compositor_frame.h" 8 #include "cc/output/compositor_frame.h"
9 #include "cc/quads/render_pass.h" 9 #include "cc/quads/render_pass.h"
10 #include "cc/quads/render_pass_draw_quad.h" 10 #include "cc/quads/render_pass_draw_quad.h"
11 #include "cc/quads/shared_quad_state.h" 11 #include "cc/quads/shared_quad_state.h"
12 #include "cc/quads/surface_draw_quad.h" 12 #include "cc/quads/surface_draw_quad.h"
13 #include "cc/surfaces/surface_id.h"
14 #include "gpu/ipc/client/gpu_channel_host.h" 13 #include "gpu/ipc/client/gpu_channel_host.h"
15 #include "services/ui/surfaces/display_compositor.h" 14 #include "services/ui/surfaces/display_compositor.h"
16 #include "services/ui/surfaces/surfaces_context_provider.h" 15 #include "services/ui/surfaces/surfaces_context_provider.h"
17 #include "services/ui/ws/frame_generator_delegate.h" 16 #include "services/ui/ws/frame_generator_delegate.h"
18 #include "services/ui/ws/server_window.h" 17 #include "services/ui/ws/server_window.h"
19 #include "services/ui/ws/server_window_compositor_frame_sink_manager.h" 18 #include "services/ui/ws/server_window_compositor_frame_sink_manager.h"
20 #include "services/ui/ws/server_window_delegate.h" 19 #include "services/ui/ws/server_window_delegate.h"
21 20
22 namespace ui { 21 namespace ui {
23 22
24 namespace ws { 23 namespace ws {
24 namespace {
25
26 // Walks up window tree and finds the SurfaceId for the ServerWindow embedding
27 // |window|. If |window| is a display root, then we return the surface
28 // manager top level root.
29 cc::SurfaceId FindParentSurfaceId(ServerWindow* window) {
30 if (!window->parent())
31 return cc::SurfaceManager::kRootSurfaceId;
32
33 ServerWindow* current = window;
34 while (current->parent()) {
35 current = current->parent();
36 if (current->compositor_frame_sink_manager() &&
37 current->compositor_frame_sink_manager()->HasCompositorFrameSinkOfType(
38 mojom::CompositorFrameSinkType::DEFAULT)) {
39 return current->compositor_frame_sink_manager()->GetLatestSurfaceId(
40 mojom::CompositorFrameSinkType::DEFAULT);
41 }
42 }
43
44 NOTREACHED();
45 return cc::SurfaceId();
46 }
47
48 } // namespace
25 49
26 FrameGenerator::FrameGenerator(FrameGeneratorDelegate* delegate, 50 FrameGenerator::FrameGenerator(FrameGeneratorDelegate* delegate,
27 ServerWindow* root_window) 51 ServerWindow* root_window)
28 : delegate_(delegate), 52 : delegate_(delegate),
29 frame_sink_id_(
30 WindowIdToTransportId(root_window->id()),
31 static_cast<uint32_t>(mojom::CompositorFrameSinkType::DEFAULT)),
32 root_window_(root_window), 53 root_window_(root_window),
33 binding_(this), 54 binding_(this),
34 weak_factory_(this) { 55 weak_factory_(this) {
35 DCHECK(delegate_); 56 DCHECK(delegate_);
36 surface_sequence_generator_.set_frame_sink_id(frame_sink_id_);
37 } 57 }
38 58
39 FrameGenerator::~FrameGenerator() { 59 FrameGenerator::~FrameGenerator() {
40 ReleaseAllSurfaceReferences(); 60 RemoveDeadSurfaceReferences();
61 RemoveAllSurfaceReferences();
41 // Invalidate WeakPtrs now to avoid callbacks back into the 62 // Invalidate WeakPtrs now to avoid callbacks back into the
42 // FrameGenerator during destruction of |compositor_frame_sink_|. 63 // FrameGenerator during destruction of |compositor_frame_sink_|.
43 weak_factory_.InvalidateWeakPtrs(); 64 weak_factory_.InvalidateWeakPtrs();
44 compositor_frame_sink_.reset(); 65 compositor_frame_sink_.reset();
45 } 66 }
46 67
47 void FrameGenerator::OnGpuChannelEstablished( 68 void FrameGenerator::OnGpuChannelEstablished(
48 scoped_refptr<gpu::GpuChannelHost> channel) { 69 scoped_refptr<gpu::GpuChannelHost> channel) {
49 if (widget_ != gfx::kNullAcceleratedWidget) { 70 if (widget_ != gfx::kNullAcceleratedWidget) {
50 cc::mojom::MojoCompositorFrameSinkRequest request = 71 cc::mojom::MojoCompositorFrameSinkRequest request =
(...skipping 28 matching lines...) Expand all
79 new SurfacesContextProvider(widget_, std::move(gpu_channel_)), 100 new SurfacesContextProvider(widget_, std::move(gpu_channel_)),
80 std::move(request), binding_.CreateInterfacePtrAndBind()); 101 std::move(request), binding_.CreateInterfacePtrAndBind());
81 // TODO(fsamuel): This means we're always requesting a new BeginFrame signal 102 // TODO(fsamuel): This means we're always requesting a new BeginFrame signal
82 // even when we don't need it. Once surface ID propagation work is done, 103 // even when we don't need it. Once surface ID propagation work is done,
83 // this will not be necessary because FrameGenerator will only need a 104 // this will not be necessary because FrameGenerator will only need a
84 // BeginFrame if the window manager changes. 105 // BeginFrame if the window manager changes.
85 compositor_frame_sink_->SetNeedsBeginFrame(true); 106 compositor_frame_sink_->SetNeedsBeginFrame(true);
86 } 107 }
87 } 108 }
88 109
110 void FrameGenerator::AddSurfaceReference(const cc::SurfaceId& surface_id,
111 ServerWindow* window) {
112 DCHECK(!surface_id.is_null());
113
114 auto it = active_references_.find(surface_id.frame_sink_id());
115 if (it == active_references_.end()) {
116 cc::SurfaceId parent_id = FindParentSurfaceId(window);
117
118 // Add new reference from parent to surface, plus add reference to local
119 // cache.
120 GetDisplayCompositor()->AddSurfaceReference(parent_id, surface_id);
121 active_references_[surface_id.frame_sink_id()] =
122 SurfaceReference({parent_id, surface_id});
123
124 // Observe |window| so that we can remove references when it's destroyed.
125 Add(window);
126 return;
127 }
128
129 SurfaceReference& ref = it->second;
130 DCHECK(surface_id.frame_sink_id() == ref.child_id.frame_sink_id());
131
132 // Check if we're holding a reference to the surface and return early.
133 if (surface_id.local_frame_id() == ref.child_id.local_frame_id())
134 return;
135
136 // Add a reference from parent to new surface first.
137 GetDisplayCompositor()->AddSurfaceReference(ref.parent_id, surface_id);
138
139 // If the display root surface has changed, update all references to embedded
140 // surfaces.
141 if (!window->parent())
142 AddNewParentReferences(ref.child_id, surface_id);
143
144 // Move the existing reference to list of references to remove after we submit
145 // the next CompositorFrame and update local reference cache to be the new
146 // reference. If this is the display root surface then removing this reference
147 // will recursively remove any references it held.
148 dead_references_.push_back(ref);
149 ref.child_id = surface_id;
150 }
151
89 void FrameGenerator::DidReceiveCompositorFrameAck() {} 152 void FrameGenerator::DidReceiveCompositorFrameAck() {}
90 153
91 void FrameGenerator::OnBeginFrame(const cc::BeginFrameArgs& begin_frame_arags) { 154 void FrameGenerator::OnBeginFrame(const cc::BeginFrameArgs& begin_frame_arags) {
92 if (!root_window_->visible()) 155 if (!root_window_->visible())
93 return; 156 return;
94 157
95 // TODO(fsamuel): We should add a trace for generating a top level frame. 158 // TODO(fsamuel): We should add a trace for generating a top level frame.
96 cc::CompositorFrame frame(GenerateCompositorFrame(root_window_->bounds())); 159 cc::CompositorFrame frame(GenerateCompositorFrame(root_window_->bounds()));
97 if (compositor_frame_sink_) 160 if (compositor_frame_sink_) {
98 compositor_frame_sink_->SubmitCompositorFrame(std::move(frame)); 161 compositor_frame_sink_->SubmitCompositorFrame(std::move(frame));
162
163 // Remove dead references after we submit a frame. This has to happen after
164 // the frame is submitted otherwise we could end up deleting a surface that
165 // is still embedded in the last frame.
166 // TODO(kylechar): This should be synchronized with SubmitCompositorFrame().
167 RemoveDeadSurfaceReferences();
168 }
99 } 169 }
100 170
101 void FrameGenerator::ReclaimResources( 171 void FrameGenerator::ReclaimResources(
102 const cc::ReturnedResourceArray& resources) { 172 const cc::ReturnedResourceArray& resources) {
103 // Nothing to do here because FrameGenerator CompositorFrames don't reference 173 // Nothing to do here because FrameGenerator CompositorFrames don't reference
104 // any resources. 174 // any resources.
105 } 175 }
106 176
107 cc::CompositorFrame FrameGenerator::GenerateCompositorFrame( 177 cc::CompositorFrame FrameGenerator::GenerateCompositorFrame(
108 const gfx::Rect& output_rect) { 178 const gfx::Rect& output_rect) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 const gfx::Rect bounds_at_origin(window->bounds().size()); 249 const gfx::Rect bounds_at_origin(window->bounds().size());
180 // TODO(fsamuel): These clipping and visible rects are incorrect. They need 250 // TODO(fsamuel): These clipping and visible rects are incorrect. They need
181 // to be populated from CompositorFrame structs. 251 // to be populated from CompositorFrame structs.
182 sqs->SetAll(quad_to_target_transform, 252 sqs->SetAll(quad_to_target_transform,
183 bounds_at_origin.size() /* layer_bounds */, 253 bounds_at_origin.size() /* layer_bounds */,
184 bounds_at_origin /* visible_layer_bounds */, 254 bounds_at_origin /* visible_layer_bounds */,
185 bounds_at_origin /* clip_rect */, false /* is_clipped */, 255 bounds_at_origin /* clip_rect */, false /* is_clipped */,
186 combined_opacity, SkXfermode::kSrcOver_Mode, 256 combined_opacity, SkXfermode::kSrcOver_Mode,
187 0 /* sorting-context_id */); 257 0 /* sorting-context_id */);
188 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>(); 258 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
189 AddOrUpdateSurfaceReference(mojom::CompositorFrameSinkType::DEFAULT,
190 window);
191 quad->SetAll(sqs, bounds_at_origin /* rect */, 259 quad->SetAll(sqs, bounds_at_origin /* rect */,
192 gfx::Rect() /* opaque_rect */, 260 gfx::Rect() /* opaque_rect */,
193 bounds_at_origin /* visible_rect */, true /* needs_blending*/, 261 bounds_at_origin /* visible_rect */, true /* needs_blending*/,
194 default_surface_id); 262 default_surface_id);
195 } 263 }
196 if (!underlay_surface_id.is_null()) { 264 if (!underlay_surface_id.is_null()) {
197 const gfx::Rect underlay_absolute_bounds = 265 const gfx::Rect underlay_absolute_bounds =
198 absolute_bounds - window->underlay_offset(); 266 absolute_bounds - window->underlay_offset();
199 gfx::Transform quad_to_target_transform; 267 gfx::Transform quad_to_target_transform;
200 quad_to_target_transform.Translate(underlay_absolute_bounds.x(), 268 quad_to_target_transform.Translate(underlay_absolute_bounds.x(),
201 underlay_absolute_bounds.y()); 269 underlay_absolute_bounds.y());
202 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); 270 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
203 const gfx::Rect bounds_at_origin( 271 const gfx::Rect bounds_at_origin(
204 window->compositor_frame_sink_manager()->GetLatestFrameSize( 272 window->compositor_frame_sink_manager()->GetLatestFrameSize(
205 mojom::CompositorFrameSinkType::UNDERLAY)); 273 mojom::CompositorFrameSinkType::UNDERLAY));
206 sqs->SetAll(quad_to_target_transform, 274 sqs->SetAll(quad_to_target_transform,
207 bounds_at_origin.size() /* layer_bounds */, 275 bounds_at_origin.size() /* layer_bounds */,
208 bounds_at_origin /* visible_layer_bounds */, 276 bounds_at_origin /* visible_layer_bounds */,
209 bounds_at_origin /* clip_rect */, false /* is_clipped */, 277 bounds_at_origin /* clip_rect */, false /* is_clipped */,
210 combined_opacity, SkXfermode::kSrcOver_Mode, 278 combined_opacity, SkXfermode::kSrcOver_Mode,
211 0 /* sorting-context_id */); 279 0 /* sorting-context_id */);
212 280
213 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>(); 281 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
214 AddOrUpdateSurfaceReference(mojom::CompositorFrameSinkType::UNDERLAY,
215 window);
216 quad->SetAll(sqs, bounds_at_origin /* rect */, 282 quad->SetAll(sqs, bounds_at_origin /* rect */,
217 gfx::Rect() /* opaque_rect */, 283 gfx::Rect() /* opaque_rect */,
218 bounds_at_origin /* visible_rect */, true /* needs_blending*/, 284 bounds_at_origin /* visible_rect */, true /* needs_blending*/,
219 underlay_surface_id); 285 underlay_surface_id);
220 } 286 }
221 } 287 }
222 288
223 void FrameGenerator::AddOrUpdateSurfaceReference( 289 void FrameGenerator::AddNewParentReferences(
224 mojom::CompositorFrameSinkType type, 290 const cc::SurfaceId& old_surface_id,
225 ServerWindow* window) { 291 const cc::SurfaceId& new_surface_id) {
226 cc::SurfaceId surface_id = 292 DCHECK(old_surface_id.frame_sink_id() == new_surface_id.frame_sink_id());
227 window->compositor_frame_sink_manager()->GetLatestSurfaceId(type); 293
228 if (surface_id.is_null()) 294 DisplayCompositor* display_compositor = GetDisplayCompositor();
229 return; 295 for (auto& map_entry : active_references_) {
230 auto it = dependencies_.find(surface_id.frame_sink_id()); 296 SurfaceReference& ref = map_entry.second;
231 if (it == dependencies_.end()) { 297 if (ref.parent_id == old_surface_id) {
232 SurfaceDependency dependency = { 298 display_compositor->AddSurfaceReference(new_surface_id, ref.child_id);
233 surface_id.local_frame_id(), 299 ref.parent_id = new_surface_id;
234 surface_sequence_generator_.CreateSurfaceSequence()}; 300 }
235 dependencies_[surface_id.frame_sink_id()] = dependency;
236 GetDisplayCompositor()->AddSurfaceReference(surface_id,
237 dependency.sequence);
238 // Observe |window_surface|'s window so that we can release references when
239 // the window is destroyed.
240 Add(window);
241 return;
242 } 301 }
302 }
243 303
244 // We are already holding a reference to this surface so there's no work to do 304 void FrameGenerator::RemoveDeadSurfaceReferences() {
245 // here. 305 if (dead_references_.empty())
246 if (surface_id.local_frame_id() == it->second.local_frame_id)
247 return; 306 return;
248 307
249 // If we have have an existing reference to a surface from the given 308 DisplayCompositor* display_compositor = GetDisplayCompositor();
250 // FrameSink, then we should release the reference, and then add this new 309 for (auto& ref : dead_references_) {
Fady Samuel 2016/11/10 13:53:02 nit: no braces necessary.
kylechar 2016/11/14 19:05:38 Acknowledged.
251 // reference. This results in a delete and lookup in the map but simplifies 310 display_compositor->RemoveSurfaceReference(ref.parent_id, ref.child_id);
252 // the code. 311 }
253 ReleaseFrameSinkReference(surface_id.frame_sink_id()); 312 dead_references_.clear();
254
255 // This recursion will always terminate. This line is being called because
256 // there was a stale surface reference. The stale reference has been released
257 // in the previous line and cleared from the dependencies_ map. Thus, in the
258 // recursive call, we'll enter the second if blcok because the FrameSinkId
259 // is no longer referenced in the map.
260 AddOrUpdateSurfaceReference(type, window);
261 } 313 }
262 314
263 void FrameGenerator::ReleaseFrameSinkReference( 315 void FrameGenerator::RemoveFrameSinkReference(
264 const cc::FrameSinkId& frame_sink_id) { 316 const cc::FrameSinkId& frame_sink_id) {
265 auto it = dependencies_.find(frame_sink_id); 317 auto it = active_references_.find(frame_sink_id);
266 if (it == dependencies_.end()) 318 if (it == active_references_.end())
267 return; 319 return;
268 std::vector<uint32_t> sequences; 320 dead_references_.push_back(it->second);
269 sequences.push_back(it->second.sequence.sequence); 321 active_references_.erase(it);
270 GetDisplayCompositor()->ReturnSurfaceReferences(frame_sink_id, sequences);
271 dependencies_.erase(it);
272 } 322 }
273 323
274 void FrameGenerator::ReleaseAllSurfaceReferences() { 324 void FrameGenerator::RemoveAllSurfaceReferences() {
275 std::vector<uint32_t> sequences; 325 DisplayCompositor* display_compositor = GetDisplayCompositor();
276 for (auto& dependency : dependencies_) 326 for (auto& map_entry : active_references_) {
277 sequences.push_back(dependency.second.sequence.sequence); 327 const SurfaceReference& ref = map_entry.second;
278 GetDisplayCompositor()->ReturnSurfaceReferences(frame_sink_id_, sequences); 328 display_compositor->RemoveSurfaceReference(ref.parent_id, ref.child_id);
279 dependencies_.clear(); 329 }
330 active_references_.clear();
280 } 331 }
281 332
282 ui::DisplayCompositor* FrameGenerator::GetDisplayCompositor() { 333 ui::DisplayCompositor* FrameGenerator::GetDisplayCompositor() {
283 return root_window_->delegate()->GetDisplayCompositor(); 334 return root_window_->delegate()->GetDisplayCompositor();
284 } 335 }
285 336
286 void FrameGenerator::OnWindowDestroying(ServerWindow* window) { 337 void FrameGenerator::OnWindowDestroying(ServerWindow* window) {
287 Remove(window); 338 Remove(window);
288 ServerWindowCompositorFrameSinkManager* compositor_frame_sink_manager = 339 ServerWindowCompositorFrameSinkManager* compositor_frame_sink_manager =
289 window->compositor_frame_sink_manager(); 340 window->compositor_frame_sink_manager();
290 // If FrameGenerator was observing |window|, then that means it had a 341 // If FrameGenerator was observing |window|, then that means it had a
291 // CompositorFrame at some point in time and should have a 342 // CompositorFrame at some point in time and should have a
292 // ServerWindowCompositorFrameSinkManager. 343 // ServerWindowCompositorFrameSinkManager.
293 DCHECK(compositor_frame_sink_manager); 344 DCHECK(compositor_frame_sink_manager);
294 345
295 cc::SurfaceId default_surface_id = 346 cc::SurfaceId default_surface_id =
296 window->compositor_frame_sink_manager()->GetLatestSurfaceId( 347 window->compositor_frame_sink_manager()->GetLatestSurfaceId(
297 mojom::CompositorFrameSinkType::DEFAULT); 348 mojom::CompositorFrameSinkType::DEFAULT);
298 if (!default_surface_id.is_null()) 349 if (!default_surface_id.is_null())
299 ReleaseFrameSinkReference(default_surface_id.frame_sink_id()); 350 RemoveFrameSinkReference(default_surface_id.frame_sink_id());
300 351
301 cc::SurfaceId underlay_surface_id = 352 cc::SurfaceId underlay_surface_id =
302 window->compositor_frame_sink_manager()->GetLatestSurfaceId( 353 window->compositor_frame_sink_manager()->GetLatestSurfaceId(
303 mojom::CompositorFrameSinkType::UNDERLAY); 354 mojom::CompositorFrameSinkType::UNDERLAY);
304 if (!underlay_surface_id.is_null()) 355 if (!underlay_surface_id.is_null())
305 ReleaseFrameSinkReference(underlay_surface_id.frame_sink_id()); 356 RemoveFrameSinkReference(underlay_surface_id.frame_sink_id());
306 } 357 }
307 358
308 } // namespace ws 359 } // namespace ws
309 360
310 } // namespace ui 361 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698