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

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

Issue 2541683004: Add/remove surface references via MojoCompositorFrameSink. (Closed)
Patch Set: Cleanup. Created 4 years 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/ui/ws/frame_generator.h ('k') | services/ui/ws/server_window_delegate.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 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 <utility>
8
7 #include "base/containers/adapters.h" 9 #include "base/containers/adapters.h"
8 #include "cc/output/compositor_frame.h" 10 #include "cc/output/compositor_frame.h"
9 #include "cc/quads/render_pass.h" 11 #include "cc/quads/render_pass.h"
10 #include "cc/quads/render_pass_draw_quad.h" 12 #include "cc/quads/render_pass_draw_quad.h"
11 #include "cc/quads/shared_quad_state.h" 13 #include "cc/quads/shared_quad_state.h"
12 #include "cc/quads/surface_draw_quad.h" 14 #include "cc/quads/surface_draw_quad.h"
13 #include "cc/surfaces/surface_id.h"
14 #include "services/ui/ws/frame_generator_delegate.h" 15 #include "services/ui/ws/frame_generator_delegate.h"
15 #include "services/ui/ws/server_window.h" 16 #include "services/ui/ws/server_window.h"
16 #include "services/ui/ws/server_window_compositor_frame_sink_manager.h" 17 #include "services/ui/ws/server_window_compositor_frame_sink_manager.h"
17 #include "services/ui/ws/server_window_delegate.h" 18 #include "services/ui/ws/server_window_delegate.h"
18 19
19 namespace ui { 20 namespace ui {
20 21
21 namespace ws { 22 namespace ws {
22 23
23 FrameGenerator::FrameGenerator(FrameGeneratorDelegate* delegate, 24 FrameGenerator::FrameGenerator(FrameGeneratorDelegate* delegate,
24 ServerWindow* root_window) 25 ServerWindow* root_window)
25 : delegate_(delegate), 26 : delegate_(delegate),
26 root_window_(root_window), 27 root_window_(root_window),
27 top_level_root_surface_id_(
28 cc::FrameSinkId(0, 0),
29 cc::LocalFrameId(0, base::UnguessableToken::Create())),
30 binding_(this), 28 binding_(this),
31 weak_factory_(this) { 29 weak_factory_(this) {
32 DCHECK(delegate_); 30 DCHECK(delegate_);
33 } 31 }
34 32
35 FrameGenerator::~FrameGenerator() { 33 FrameGenerator::~FrameGenerator() {
36 RemoveDeadSurfaceReferences();
37 RemoveAllSurfaceReferences(); 34 RemoveAllSurfaceReferences();
38 // Invalidate WeakPtrs now to avoid callbacks back into the 35 // Invalidate WeakPtrs now to avoid callbacks back into the
39 // FrameGenerator during destruction of |compositor_frame_sink_|. 36 // FrameGenerator during destruction of |compositor_frame_sink_|.
40 weak_factory_.InvalidateWeakPtrs(); 37 weak_factory_.InvalidateWeakPtrs();
41 compositor_frame_sink_.reset(); 38 compositor_frame_sink_.reset();
42 } 39 }
43 40
44 void FrameGenerator::OnAcceleratedWidgetAvailable( 41 void FrameGenerator::OnAcceleratedWidgetAvailable(
45 gfx::AcceleratedWidget widget) { 42 gfx::AcceleratedWidget widget) {
46 DCHECK_NE(gfx::kNullAcceleratedWidget, widget); 43 DCHECK_NE(gfx::kNullAcceleratedWidget, widget);
47 cc::mojom::MojoCompositorFrameSinkRequest request = 44 cc::mojom::MojoCompositorFrameSinkRequest request =
48 mojo::GetProxy(&compositor_frame_sink_); 45 mojo::GetProxy(&compositor_frame_sink_);
49 root_window_->CreateCompositorFrameSink( 46 root_window_->CreateCompositorFrameSink(
50 mojom::CompositorFrameSinkType::DEFAULT, widget, std::move(request), 47 mojom::CompositorFrameSinkType::DEFAULT, widget, std::move(request),
51 binding_.CreateInterfacePtrAndBind()); 48 binding_.CreateInterfacePtrAndBind());
52 // TODO(fsamuel): This means we're always requesting a new BeginFrame signal 49 // TODO(fsamuel): This means we're always requesting a new BeginFrame signal
53 // even when we don't need it. Once surface ID propagation work is done, 50 // even when we don't need it. Once surface ID propagation work is done,
54 // this will not be necessary because FrameGenerator will only need a 51 // this will not be necessary because FrameGenerator will only need a
55 // BeginFrame if the window manager changes. 52 // BeginFrame if the window manager changes.
56 compositor_frame_sink_->SetNeedsBeginFrame(true); 53 compositor_frame_sink_->SetNeedsBeginFrame(true);
57 } 54 }
58 55
59 void FrameGenerator::OnSurfaceCreated(const cc::SurfaceId& surface_id, 56 void FrameGenerator::OnSurfaceCreated(const cc::SurfaceId& surface_id,
60 ServerWindow* window) { 57 ServerWindow* window) {
61 DCHECK(surface_id.is_valid()); 58 DCHECK(surface_id.is_valid());
62 59
63 // TODO(kylechar): Adding surface references should be synchronized with
64 // SubmitCompositorFrame().
65
66 auto iter = active_references_.find(surface_id.frame_sink_id()); 60 auto iter = active_references_.find(surface_id.frame_sink_id());
67 if (iter == active_references_.end()) { 61 if (iter == active_references_.end()) {
68 AddFirstReference(surface_id, window); 62 AddFirstReference(surface_id, window);
69 return; 63 return;
70 } 64 }
71 65
72 SurfaceReference& ref = iter->second; 66 cc::SurfaceReference& ref = iter->second;
73 DCHECK_EQ(surface_id.frame_sink_id(), ref.child_id.frame_sink_id());
74 67
75 // This shouldn't be called multiple times for the same SurfaceId. 68 // This shouldn't be called multiple times for the same SurfaceId.
76 DCHECK_NE(surface_id.local_frame_id(), ref.child_id.local_frame_id()); 69 DCHECK_EQ(surface_id.frame_sink_id(), ref.child_id().frame_sink_id());
70 DCHECK_NE(surface_id.local_frame_id(), ref.child_id().local_frame_id());
77 71
78 // Add a reference from parent to new surface first. 72 // The current reference will be removed after the next CompositorFrame is
79 GetDisplayCompositor()->AddSurfaceReference(ref.parent_id, surface_id); 73 // submitted or FrameGenerator is destroyed.
74 references_to_remove_.push_back(ref);
75 cc::SurfaceId old_surface_id = ref.child_id();
80 76
81 // If the display root surface has changed, update all references to embedded 77 // New surface reference is recorded and will be added at end of this method.
82 // surfaces. For example, this would happen when the display resolution or 78 ref = cc::SurfaceReference(ref.parent_id(), surface_id);
83 // zoom level changes. 79 references_to_add_.push_back(ref);
84 if (!window->parent())
85 AddNewParentReferences(ref.child_id, surface_id);
86 80
87 // Move the existing reference to list of references to remove after we submit 81 // If the display root surface has changed, add references from the new
88 // the next CompositorFrame. Update local reference cache to be the new 82 // SurfaceId to all embedded surfaces. For example, this would happen when the
89 // reference. If this is the display root surface then removing this reference 83 // display resolution or device scale factor changes.
90 // will recursively remove any references it held. 84 if (window == root_window_)
91 dead_references_.push_back(ref); 85 AddNewParentReferences(old_surface_id, surface_id);
92 ref.child_id = surface_id; 86
87 PerformAddSurfaceReferences();
93 } 88 }
94 89
95 void FrameGenerator::DidReceiveCompositorFrameAck() {} 90 void FrameGenerator::DidReceiveCompositorFrameAck() {}
96 91
97 void FrameGenerator::OnBeginFrame(const cc::BeginFrameArgs& begin_frame_arags) { 92 void FrameGenerator::OnBeginFrame(const cc::BeginFrameArgs& begin_frame_arags) {
98 if (!root_window_->visible()) 93 if (!root_window_->visible())
99 return; 94 return;
100 95
101 // TODO(fsamuel): We should add a trace for generating a top level frame. 96 // TODO(fsamuel): We should add a trace for generating a top level frame.
102 cc::CompositorFrame frame(GenerateCompositorFrame(root_window_->bounds())); 97 cc::CompositorFrame frame(GenerateCompositorFrame(root_window_->bounds()));
103 98
104 if (compositor_frame_sink_) { 99 if (compositor_frame_sink_) {
105 gfx::Size frame_size = last_submitted_frame_size_; 100 gfx::Size frame_size = last_submitted_frame_size_;
106 if (!frame.render_pass_list.empty()) 101 if (!frame.render_pass_list.empty())
107 frame_size = frame.render_pass_list[0]->output_rect.size(); 102 frame_size = frame.render_pass_list[0]->output_rect.size();
108 if (!local_frame_id_.is_valid() || frame_size != last_submitted_frame_size_) 103 if (!local_frame_id_.is_valid() || frame_size != last_submitted_frame_size_)
109 local_frame_id_ = id_allocator_.GenerateId(); 104 local_frame_id_ = id_allocator_.GenerateId();
110 compositor_frame_sink_->SubmitCompositorFrame(local_frame_id_, 105 compositor_frame_sink_->SubmitCompositorFrame(local_frame_id_,
111 std::move(frame)); 106 std::move(frame));
112 last_submitted_frame_size_ = frame_size; 107 last_submitted_frame_size_ = frame_size;
113 108
114 // Remove dead references after we submit a frame. This has to happen after 109 // Remove dead references after we submit a frame. This has to happen after
115 // the frame is submitted otherwise we could end up deleting a surface that 110 // the frame is submitted otherwise we could end up deleting a surface that
116 // is still embedded in the last frame. 111 // is still embedded in the last frame.
117 // TODO(kylechar): This should be synchronized with SubmitCompositorFrame(). 112 PerformRemoveSurfaceReferences();
118 RemoveDeadSurfaceReferences();
119 } 113 }
120 } 114 }
121 115
122 void FrameGenerator::ReclaimResources( 116 void FrameGenerator::ReclaimResources(
123 const cc::ReturnedResourceArray& resources) { 117 const cc::ReturnedResourceArray& resources) {
124 // Nothing to do here because FrameGenerator CompositorFrames don't reference 118 // Nothing to do here because FrameGenerator CompositorFrames don't reference
125 // any resources. 119 // any resources.
126 } 120 }
127 121
128 void FrameGenerator::WillDrawSurface() { 122 void FrameGenerator::WillDrawSurface() {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>(); 228 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
235 quad->SetAll(sqs, bounds_at_origin /* rect */, 229 quad->SetAll(sqs, bounds_at_origin /* rect */,
236 gfx::Rect() /* opaque_rect */, 230 gfx::Rect() /* opaque_rect */,
237 bounds_at_origin /* visible_rect */, true /* needs_blending*/, 231 bounds_at_origin /* visible_rect */, true /* needs_blending*/,
238 underlay_surface_id); 232 underlay_surface_id);
239 } 233 }
240 } 234 }
241 235
242 cc::SurfaceId FrameGenerator::FindParentSurfaceId(ServerWindow* window) { 236 cc::SurfaceId FrameGenerator::FindParentSurfaceId(ServerWindow* window) {
243 if (window == root_window_) 237 if (window == root_window_)
244 return top_level_root_surface_id_; 238 return root_window_->delegate()->GetRootSurfaceId();
245 239
246 // The root window holds the parent SurfaceId. This SurfaceId will have an 240 // The root window holds the parent SurfaceId. This SurfaceId will have an
247 // invalid LocalFrameId before FrameGenerator has submitted a CompositorFrame. 241 // invalid LocalFrameId before FrameGenerator has submitted a CompositorFrame.
248 // After the first frame is submitted it will always be a valid SurfaceId. 242 // After the first frame is submitted it will always be a valid SurfaceId.
249 return root_window_->compositor_frame_sink_manager()->GetLatestSurfaceId( 243 return root_window_->compositor_frame_sink_manager()->GetLatestSurfaceId(
250 mojom::CompositorFrameSinkType::DEFAULT); 244 mojom::CompositorFrameSinkType::DEFAULT);
251 } 245 }
252 246
253 void FrameGenerator::AddSurfaceReference(const cc::SurfaceId& parent_id, 247 void FrameGenerator::AddSurfaceReference(const cc::SurfaceId& parent_id,
254 const cc::SurfaceId& child_id) { 248 const cc::SurfaceId& child_id) {
255 if (parent_id == top_level_root_surface_id_) 249 DCHECK_NE(parent_id, child_id);
256 GetDisplayCompositor()->AddRootSurfaceReference(child_id);
257 else
258 GetDisplayCompositor()->AddSurfaceReference(parent_id, child_id);
259 250
260 // Add new reference from parent to surface, plus add reference to local 251 // Add new reference from parent to surface and record reference.
261 // cache. 252 cc::SurfaceReference ref(parent_id, child_id);
262 active_references_[child_id.frame_sink_id()] = 253 active_references_[child_id.frame_sink_id()] = ref;
263 SurfaceReference({parent_id, child_id}); 254 references_to_add_.push_back(ref);
264 } 255 }
265 256
266 void FrameGenerator::AddFirstReference(const cc::SurfaceId& surface_id, 257 void FrameGenerator::AddFirstReference(const cc::SurfaceId& surface_id,
267 ServerWindow* window) { 258 ServerWindow* window) {
268 cc::SurfaceId parent_id = FindParentSurfaceId(window); 259 cc::SurfaceId parent_id = FindParentSurfaceId(window);
269 260
270 if (parent_id == top_level_root_surface_id_ || parent_id.is_valid()) { 261 if (parent_id.local_frame_id().is_valid()) {
271 AddSurfaceReference(parent_id, surface_id); 262 AddSurfaceReference(parent_id, surface_id);
272 263
273 // For the first display root surface, add references to any child surfaces 264 // For the first display root surface, add references to any child surfaces
274 // that were created before it. 265 // that were created before it, since no reference has been added yet.
275 if (parent_id == top_level_root_surface_id_) { 266 if (window == root_window_) {
276 for (auto& child_surface_id : waiting_for_references_) 267 for (auto& child_surface_id : waiting_for_references_)
277 AddSurfaceReference(surface_id, child_surface_id); 268 AddSurfaceReference(surface_id, child_surface_id);
278 waiting_for_references_.clear(); 269 waiting_for_references_.clear();
279 } 270 }
271
272 PerformAddSurfaceReferences();
280 } else { 273 } else {
281 // This isn't the display root surface and display root surface hasn't 274 // This isn't the display root surface and display root surface hasn't
282 // submitted a CF yet. We can't add a reference to an unknown SurfaceId. 275 // submitted a CF yet. We can't add a reference to an unknown SurfaceId.
283 waiting_for_references_.push_back(surface_id); 276 waiting_for_references_.push_back(surface_id);
284 } 277 }
285 278
286 // Observe |window| so that we can remove references when it's destroyed. 279 // Observe |window| so that we can remove references when it's destroyed.
287 Add(window); 280 Add(window);
288 } 281 }
289 282
290 void FrameGenerator::AddNewParentReferences( 283 void FrameGenerator::AddNewParentReferences(
291 const cc::SurfaceId& old_surface_id, 284 const cc::SurfaceId& old_surface_id,
292 const cc::SurfaceId& new_surface_id) { 285 const cc::SurfaceId& new_surface_id) {
293 DCHECK(old_surface_id.frame_sink_id() == new_surface_id.frame_sink_id()); 286 DCHECK_EQ(old_surface_id.frame_sink_id(), new_surface_id.frame_sink_id());
294 287
295 cc::mojom::DisplayCompositor* display_compositor = GetDisplayCompositor();
296 for (auto& map_entry : active_references_) { 288 for (auto& map_entry : active_references_) {
297 SurfaceReference& ref = map_entry.second; 289 cc::SurfaceReference& ref = map_entry.second;
298 if (ref.parent_id == old_surface_id) { 290 if (ref.parent_id() == old_surface_id) {
299 display_compositor->AddSurfaceReference(new_surface_id, ref.child_id); 291 ref = cc::SurfaceReference(new_surface_id, ref.child_id());
300 ref.parent_id = new_surface_id; 292 references_to_add_.push_back(ref);
301 } 293 }
302 } 294 }
303 } 295 }
304 296
305 void FrameGenerator::RemoveDeadSurfaceReferences() { 297 void FrameGenerator::PerformAddSurfaceReferences() {
306 if (dead_references_.empty()) 298 if (references_to_add_.empty())
307 return; 299 return;
308 300
309 cc::mojom::DisplayCompositor* display_compositor = GetDisplayCompositor(); 301 compositor_frame_sink_->AddSurfaceReferences(references_to_add_);
310 for (auto& ref : dead_references_) { 302 references_to_add_.clear();
311 if (ref.parent_id == top_level_root_surface_id_) 303 }
312 display_compositor->RemoveRootSurfaceReference(ref.child_id); 304
313 else 305 void FrameGenerator::PerformRemoveSurfaceReferences() {
314 display_compositor->RemoveSurfaceReference(ref.parent_id, ref.child_id); 306 if (references_to_remove_.empty())
315 } 307 return;
316 dead_references_.clear(); 308
309 compositor_frame_sink_->RemoveSurfaceReferences(references_to_remove_);
310 references_to_remove_.clear();
317 } 311 }
318 312
319 void FrameGenerator::RemoveFrameSinkReference( 313 void FrameGenerator::RemoveFrameSinkReference(
320 const cc::FrameSinkId& frame_sink_id) { 314 const cc::FrameSinkId& frame_sink_id) {
321 auto it = active_references_.find(frame_sink_id); 315 auto it = active_references_.find(frame_sink_id);
322 if (it == active_references_.end()) 316 if (it == active_references_.end())
323 return; 317 return;
324 dead_references_.push_back(it->second); 318 references_to_remove_.push_back(it->second);
325 active_references_.erase(it); 319 active_references_.erase(it);
326 } 320 }
327 321
328 void FrameGenerator::RemoveAllSurfaceReferences() { 322 void FrameGenerator::RemoveAllSurfaceReferences() {
329 // TODO(kylechar): Remove multiple surfaces with one IPC call. 323 for (auto& map_entry : active_references_)
330 cc::mojom::DisplayCompositor* display_compositor = GetDisplayCompositor(); 324 references_to_remove_.push_back(map_entry.second);
331 for (auto& map_entry : active_references_) {
332 const SurfaceReference& ref = map_entry.second;
333 display_compositor->RemoveSurfaceReference(ref.parent_id, ref.child_id);
334 }
335 active_references_.clear(); 325 active_references_.clear();
336 } 326 PerformRemoveSurfaceReferences();
337
338 cc::mojom::DisplayCompositor* FrameGenerator::GetDisplayCompositor() {
339 return root_window_->delegate()->GetDisplayCompositor();
340 } 327 }
341 328
342 void FrameGenerator::OnWindowDestroying(ServerWindow* window) { 329 void FrameGenerator::OnWindowDestroying(ServerWindow* window) {
343 Remove(window); 330 Remove(window);
344 ServerWindowCompositorFrameSinkManager* compositor_frame_sink_manager = 331 ServerWindowCompositorFrameSinkManager* compositor_frame_sink_manager =
345 window->compositor_frame_sink_manager(); 332 window->compositor_frame_sink_manager();
346 // If FrameGenerator was observing |window|, then that means it had a 333 // If FrameGenerator was observing |window|, then that means it had a
347 // CompositorFrame at some point in time and should have a 334 // CompositorFrame at some point in time and should have a
348 // ServerWindowCompositorFrameSinkManager. 335 // ServerWindowCompositorFrameSinkManager.
349 DCHECK(compositor_frame_sink_manager); 336 DCHECK(compositor_frame_sink_manager);
350 337
351 cc::SurfaceId default_surface_id = 338 cc::SurfaceId default_surface_id =
352 window->compositor_frame_sink_manager()->GetLatestSurfaceId( 339 window->compositor_frame_sink_manager()->GetLatestSurfaceId(
353 mojom::CompositorFrameSinkType::DEFAULT); 340 mojom::CompositorFrameSinkType::DEFAULT);
354 if (default_surface_id.is_valid()) 341 if (default_surface_id.is_valid())
355 RemoveFrameSinkReference(default_surface_id.frame_sink_id()); 342 RemoveFrameSinkReference(default_surface_id.frame_sink_id());
356 343
357 cc::SurfaceId underlay_surface_id = 344 cc::SurfaceId underlay_surface_id =
358 window->compositor_frame_sink_manager()->GetLatestSurfaceId( 345 window->compositor_frame_sink_manager()->GetLatestSurfaceId(
359 mojom::CompositorFrameSinkType::UNDERLAY); 346 mojom::CompositorFrameSinkType::UNDERLAY);
360 if (underlay_surface_id.is_valid()) 347 if (underlay_surface_id.is_valid())
361 RemoveFrameSinkReference(underlay_surface_id.frame_sink_id()); 348 RemoveFrameSinkReference(underlay_surface_id.frame_sink_id());
362 } 349 }
363 350
364 } // namespace ws 351 } // namespace ws
365 352
366 } // namespace ui 353 } // namespace ui
OLDNEW
« no previous file with comments | « services/ui/ws/frame_generator.h ('k') | services/ui/ws/server_window_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698