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

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

Issue 2489003002: Convert mustash use surface references. (Closed)
Patch Set: More fixes for comments. 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/platform_display.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 "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 {
25 24
26 FrameGenerator::FrameGenerator(FrameGeneratorDelegate* delegate, 25 FrameGenerator::FrameGenerator(FrameGeneratorDelegate* delegate,
27 ServerWindow* root_window) 26 ServerWindow* root_window)
28 : delegate_(delegate), 27 : delegate_(delegate),
29 frame_sink_id_(
30 WindowIdToTransportId(root_window->id()),
31 static_cast<uint32_t>(mojom::CompositorFrameSinkType::DEFAULT)),
32 root_window_(root_window), 28 root_window_(root_window),
29 top_level_root_surface_id_(
30 cc::FrameSinkId(0, 0),
31 cc::LocalFrameId(0, base::UnguessableToken::Create())),
33 binding_(this), 32 binding_(this),
34 weak_factory_(this) { 33 weak_factory_(this) {
35 DCHECK(delegate_); 34 DCHECK(delegate_);
36 surface_sequence_generator_.set_frame_sink_id(frame_sink_id_);
37 } 35 }
38 36
39 FrameGenerator::~FrameGenerator() { 37 FrameGenerator::~FrameGenerator() {
40 ReleaseAllSurfaceReferences(); 38 RemoveDeadSurfaceReferences();
39 RemoveAllSurfaceReferences();
41 // Invalidate WeakPtrs now to avoid callbacks back into the 40 // Invalidate WeakPtrs now to avoid callbacks back into the
42 // FrameGenerator during destruction of |compositor_frame_sink_|. 41 // FrameGenerator during destruction of |compositor_frame_sink_|.
43 weak_factory_.InvalidateWeakPtrs(); 42 weak_factory_.InvalidateWeakPtrs();
44 compositor_frame_sink_.reset(); 43 compositor_frame_sink_.reset();
45 } 44 }
46 45
47 void FrameGenerator::OnGpuChannelEstablished( 46 void FrameGenerator::OnGpuChannelEstablished(
48 scoped_refptr<gpu::GpuChannelHost> channel) { 47 scoped_refptr<gpu::GpuChannelHost> channel) {
49 if (widget_ != gfx::kNullAcceleratedWidget) { 48 if (widget_ != gfx::kNullAcceleratedWidget) {
50 cc::mojom::MojoCompositorFrameSinkRequest request = 49 cc::mojom::MojoCompositorFrameSinkRequest request =
(...skipping 28 matching lines...) Expand all
79 new SurfacesContextProvider(widget_, gpu_channel_), 78 new SurfacesContextProvider(widget_, gpu_channel_),
80 std::move(request), binding_.CreateInterfacePtrAndBind()); 79 std::move(request), binding_.CreateInterfacePtrAndBind());
81 // TODO(fsamuel): This means we're always requesting a new BeginFrame signal 80 // 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, 81 // 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 82 // this will not be necessary because FrameGenerator will only need a
84 // BeginFrame if the window manager changes. 83 // BeginFrame if the window manager changes.
85 compositor_frame_sink_->SetNeedsBeginFrame(true); 84 compositor_frame_sink_->SetNeedsBeginFrame(true);
86 } 85 }
87 } 86 }
88 87
88 void FrameGenerator::OnSurfaceCreated(const cc::SurfaceId& surface_id,
89 ServerWindow* window) {
90 DCHECK(surface_id.is_valid());
91
92 // TODO(kylechar): Adding surface references should be synchronized with
93 // SubmitCompositorFrame().
94
95 auto iter = active_references_.find(surface_id.frame_sink_id());
96 if (iter == active_references_.end()) {
97 AddFirstReference(surface_id, window);
98 return;
99 }
100
101 SurfaceReference& ref = iter->second;
102 DCHECK(surface_id.frame_sink_id() == ref.child_id.frame_sink_id());
103
104 // This shouldn't be called multiple times for the same SurfaceId.
105 DCHECK(surface_id.local_frame_id() != ref.child_id.local_frame_id());
106
107 // Add a reference from parent to new surface first.
108 GetDisplayCompositor()->AddSurfaceReference(ref.parent_id, surface_id);
109
110 // If the display root surface has changed, update all references to embedded
111 // surfaces. For example, this would happen when the display resolution or
112 // zoom level changes.
113 if (!window->parent())
114 AddNewParentReferences(ref.child_id, surface_id);
115
116 // Move the existing reference to list of references to remove after we submit
117 // the next CompositorFrame. Update local reference cache to be the new
118 // reference. If this is the display root surface then removing this reference
119 // will recursively remove any references it held.
120 dead_references_.push_back(ref);
121 ref.child_id = surface_id;
122 }
123
89 void FrameGenerator::DidReceiveCompositorFrameAck() {} 124 void FrameGenerator::DidReceiveCompositorFrameAck() {}
90 125
91 void FrameGenerator::OnBeginFrame(const cc::BeginFrameArgs& begin_frame_arags) { 126 void FrameGenerator::OnBeginFrame(const cc::BeginFrameArgs& begin_frame_arags) {
92 if (!root_window_->visible()) 127 if (!root_window_->visible())
93 return; 128 return;
94 129
95 // TODO(fsamuel): We should add a trace for generating a top level frame. 130 // TODO(fsamuel): We should add a trace for generating a top level frame.
96 cc::CompositorFrame frame(GenerateCompositorFrame(root_window_->bounds())); 131 cc::CompositorFrame frame(GenerateCompositorFrame(root_window_->bounds()));
97 if (compositor_frame_sink_) 132 if (compositor_frame_sink_) {
98 compositor_frame_sink_->SubmitCompositorFrame(std::move(frame)); 133 compositor_frame_sink_->SubmitCompositorFrame(std::move(frame));
134
135 // Remove dead references after we submit a frame. This has to happen after
136 // the frame is submitted otherwise we could end up deleting a surface that
137 // is still embedded in the last frame.
138 // TODO(kylechar): This should be synchronized with SubmitCompositorFrame().
139 RemoveDeadSurfaceReferences();
140 }
99 } 141 }
100 142
101 void FrameGenerator::ReclaimResources( 143 void FrameGenerator::ReclaimResources(
102 const cc::ReturnedResourceArray& resources) { 144 const cc::ReturnedResourceArray& resources) {
103 // Nothing to do here because FrameGenerator CompositorFrames don't reference 145 // Nothing to do here because FrameGenerator CompositorFrames don't reference
104 // any resources. 146 // any resources.
105 } 147 }
106 148
107 cc::CompositorFrame FrameGenerator::GenerateCompositorFrame( 149 cc::CompositorFrame FrameGenerator::GenerateCompositorFrame(
108 const gfx::Rect& output_rect) { 150 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()); 221 const gfx::Rect bounds_at_origin(window->bounds().size());
180 // TODO(fsamuel): These clipping and visible rects are incorrect. They need 222 // TODO(fsamuel): These clipping and visible rects are incorrect. They need
181 // to be populated from CompositorFrame structs. 223 // to be populated from CompositorFrame structs.
182 sqs->SetAll(quad_to_target_transform, 224 sqs->SetAll(quad_to_target_transform,
183 bounds_at_origin.size() /* layer_bounds */, 225 bounds_at_origin.size() /* layer_bounds */,
184 bounds_at_origin /* visible_layer_bounds */, 226 bounds_at_origin /* visible_layer_bounds */,
185 bounds_at_origin /* clip_rect */, false /* is_clipped */, 227 bounds_at_origin /* clip_rect */, false /* is_clipped */,
186 combined_opacity, SkXfermode::kSrcOver_Mode, 228 combined_opacity, SkXfermode::kSrcOver_Mode,
187 0 /* sorting-context_id */); 229 0 /* sorting-context_id */);
188 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>(); 230 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
189 AddOrUpdateSurfaceReference(mojom::CompositorFrameSinkType::DEFAULT,
190 window);
191 quad->SetAll(sqs, bounds_at_origin /* rect */, 231 quad->SetAll(sqs, bounds_at_origin /* rect */,
192 gfx::Rect() /* opaque_rect */, 232 gfx::Rect() /* opaque_rect */,
193 bounds_at_origin /* visible_rect */, true /* needs_blending*/, 233 bounds_at_origin /* visible_rect */, true /* needs_blending*/,
194 default_surface_id); 234 default_surface_id);
195 } 235 }
196 if (underlay_surface_id.is_valid()) { 236 if (underlay_surface_id.is_valid()) {
197 const gfx::Rect underlay_absolute_bounds = 237 const gfx::Rect underlay_absolute_bounds =
198 absolute_bounds - window->underlay_offset(); 238 absolute_bounds - window->underlay_offset();
199 gfx::Transform quad_to_target_transform; 239 gfx::Transform quad_to_target_transform;
200 quad_to_target_transform.Translate(underlay_absolute_bounds.x(), 240 quad_to_target_transform.Translate(underlay_absolute_bounds.x(),
201 underlay_absolute_bounds.y()); 241 underlay_absolute_bounds.y());
202 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); 242 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
203 const gfx::Rect bounds_at_origin( 243 const gfx::Rect bounds_at_origin(
204 window->compositor_frame_sink_manager()->GetLatestFrameSize( 244 window->compositor_frame_sink_manager()->GetLatestFrameSize(
205 mojom::CompositorFrameSinkType::UNDERLAY)); 245 mojom::CompositorFrameSinkType::UNDERLAY));
206 sqs->SetAll(quad_to_target_transform, 246 sqs->SetAll(quad_to_target_transform,
207 bounds_at_origin.size() /* layer_bounds */, 247 bounds_at_origin.size() /* layer_bounds */,
208 bounds_at_origin /* visible_layer_bounds */, 248 bounds_at_origin /* visible_layer_bounds */,
209 bounds_at_origin /* clip_rect */, false /* is_clipped */, 249 bounds_at_origin /* clip_rect */, false /* is_clipped */,
210 combined_opacity, SkXfermode::kSrcOver_Mode, 250 combined_opacity, SkXfermode::kSrcOver_Mode,
211 0 /* sorting-context_id */); 251 0 /* sorting-context_id */);
212 252
213 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>(); 253 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
214 AddOrUpdateSurfaceReference(mojom::CompositorFrameSinkType::UNDERLAY,
215 window);
216 quad->SetAll(sqs, bounds_at_origin /* rect */, 254 quad->SetAll(sqs, bounds_at_origin /* rect */,
217 gfx::Rect() /* opaque_rect */, 255 gfx::Rect() /* opaque_rect */,
218 bounds_at_origin /* visible_rect */, true /* needs_blending*/, 256 bounds_at_origin /* visible_rect */, true /* needs_blending*/,
219 underlay_surface_id); 257 underlay_surface_id);
220 } 258 }
221 } 259 }
222 260
223 void FrameGenerator::AddOrUpdateSurfaceReference( 261 cc::SurfaceId FrameGenerator::FindParentSurfaceId(ServerWindow* window) {
224 mojom::CompositorFrameSinkType type, 262 if (window == root_window_)
225 ServerWindow* window) { 263 return top_level_root_surface_id_;
226 cc::SurfaceId surface_id = 264
227 window->compositor_frame_sink_manager()->GetLatestSurfaceId(type); 265 // The root window holds the parent SurfaceId. This SurfaceId will have an
228 if (!surface_id.is_valid()) 266 // invalid LocalFrameId before FrameGenerator has submitted a CompositorFrame.
229 return; 267 // After the first frame is submitted it will always be a valid SurfaceId.
230 auto it = dependencies_.find(surface_id.frame_sink_id()); 268 return root_window_->compositor_frame_sink_manager()->GetLatestSurfaceId(
231 if (it == dependencies_.end()) { 269 mojom::CompositorFrameSinkType::DEFAULT);
232 SurfaceDependency dependency = { 270 }
233 surface_id.local_frame_id(), 271
234 surface_sequence_generator_.CreateSurfaceSequence()}; 272 void FrameGenerator::AddSurfaceReference(const cc::SurfaceId& parent_id,
235 dependencies_[surface_id.frame_sink_id()] = dependency; 273 const cc::SurfaceId& child_id) {
236 GetDisplayCompositor()->AddSurfaceReference(surface_id, 274 if (parent_id == top_level_root_surface_id_)
237 dependency.sequence); 275 GetDisplayCompositor()->AddRootSurfaceReference(child_id);
238 // Observe |window_surface|'s window so that we can release references when 276 else
239 // the window is destroyed. 277 GetDisplayCompositor()->AddSurfaceReference(parent_id, child_id);
240 Add(window); 278
241 return; 279 // Add new reference from parent to surface, plus add reference to local
280 // cache.
281 active_references_[child_id.frame_sink_id()] =
282 SurfaceReference({parent_id, child_id});
283 }
284
285 void FrameGenerator::AddFirstReference(const cc::SurfaceId& surface_id,
286 ServerWindow* window) {
287 cc::SurfaceId parent_id = FindParentSurfaceId(window);
288
289 if (parent_id == top_level_root_surface_id_ || parent_id.is_valid()) {
290 AddSurfaceReference(parent_id, surface_id);
291
292 // For the first display root surface, add references to any child surfaces
293 // that were created before it.
294 if (parent_id == top_level_root_surface_id_) {
295 for (auto& child_surface_id : waiting_for_references_)
296 AddSurfaceReference(surface_id, child_surface_id);
297 waiting_for_references_.clear();
298 }
299 } else {
300 // This isn't the display root surface and display root surface hasn't
301 // submitted a CF yet. We can't add a reference to an unknown SurfaceId.
302 waiting_for_references_.push_back(surface_id);
242 } 303 }
243 304
244 // We are already holding a reference to this surface so there's no work to do 305 // Observe |window| so that we can remove references when it's destroyed.
245 // here. 306 Add(window);
246 if (surface_id.local_frame_id() == it->second.local_frame_id) 307 }
308
309 void FrameGenerator::AddNewParentReferences(
310 const cc::SurfaceId& old_surface_id,
311 const cc::SurfaceId& new_surface_id) {
312 DCHECK(old_surface_id.frame_sink_id() == new_surface_id.frame_sink_id());
313
314 DisplayCompositor* display_compositor = GetDisplayCompositor();
315 for (auto& map_entry : active_references_) {
316 SurfaceReference& ref = map_entry.second;
317 if (ref.parent_id == old_surface_id) {
318 display_compositor->AddSurfaceReference(new_surface_id, ref.child_id);
319 ref.parent_id = new_surface_id;
320 }
321 }
322 }
323
324 void FrameGenerator::RemoveDeadSurfaceReferences() {
325 if (dead_references_.empty())
247 return; 326 return;
248 327
249 // If we have have an existing reference to a surface from the given 328 DisplayCompositor* display_compositor = GetDisplayCompositor();
250 // FrameSink, then we should release the reference, and then add this new 329 for (auto& ref : dead_references_) {
251 // reference. This results in a delete and lookup in the map but simplifies 330 if (ref.parent_id == top_level_root_surface_id_)
252 // the code. 331 display_compositor->RemoveRootSurfaceReference(ref.child_id);
253 ReleaseFrameSinkReference(surface_id.frame_sink_id()); 332 else
254 333 display_compositor->RemoveSurfaceReference(ref.parent_id, ref.child_id);
255 // This recursion will always terminate. This line is being called because 334 }
256 // there was a stale surface reference. The stale reference has been released 335 dead_references_.clear();
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 } 336 }
262 337
263 void FrameGenerator::ReleaseFrameSinkReference( 338 void FrameGenerator::RemoveFrameSinkReference(
264 const cc::FrameSinkId& frame_sink_id) { 339 const cc::FrameSinkId& frame_sink_id) {
265 auto it = dependencies_.find(frame_sink_id); 340 auto it = active_references_.find(frame_sink_id);
266 if (it == dependencies_.end()) 341 if (it == active_references_.end())
267 return; 342 return;
268 std::vector<uint32_t> sequences; 343 dead_references_.push_back(it->second);
269 sequences.push_back(it->second.sequence.sequence); 344 active_references_.erase(it);
270 GetDisplayCompositor()->ReturnSurfaceReferences(frame_sink_id, sequences);
271 dependencies_.erase(it);
272 } 345 }
273 346
274 void FrameGenerator::ReleaseAllSurfaceReferences() { 347 void FrameGenerator::RemoveAllSurfaceReferences() {
275 std::vector<uint32_t> sequences; 348 // TODO(kylechar): Remove multiple surfaces with one IPC call.
276 for (auto& dependency : dependencies_) 349 DisplayCompositor* display_compositor = GetDisplayCompositor();
277 sequences.push_back(dependency.second.sequence.sequence); 350 for (auto& map_entry : active_references_) {
278 GetDisplayCompositor()->ReturnSurfaceReferences(frame_sink_id_, sequences); 351 const SurfaceReference& ref = map_entry.second;
279 dependencies_.clear(); 352 display_compositor->RemoveSurfaceReference(ref.parent_id, ref.child_id);
353 }
354 active_references_.clear();
280 } 355 }
281 356
282 ui::DisplayCompositor* FrameGenerator::GetDisplayCompositor() { 357 ui::DisplayCompositor* FrameGenerator::GetDisplayCompositor() {
283 return root_window_->delegate()->GetDisplayCompositor(); 358 return root_window_->delegate()->GetDisplayCompositor();
284 } 359 }
285 360
286 void FrameGenerator::OnWindowDestroying(ServerWindow* window) { 361 void FrameGenerator::OnWindowDestroying(ServerWindow* window) {
287 Remove(window); 362 Remove(window);
288 ServerWindowCompositorFrameSinkManager* compositor_frame_sink_manager = 363 ServerWindowCompositorFrameSinkManager* compositor_frame_sink_manager =
289 window->compositor_frame_sink_manager(); 364 window->compositor_frame_sink_manager();
290 // If FrameGenerator was observing |window|, then that means it had a 365 // If FrameGenerator was observing |window|, then that means it had a
291 // CompositorFrame at some point in time and should have a 366 // CompositorFrame at some point in time and should have a
292 // ServerWindowCompositorFrameSinkManager. 367 // ServerWindowCompositorFrameSinkManager.
293 DCHECK(compositor_frame_sink_manager); 368 DCHECK(compositor_frame_sink_manager);
294 369
295 cc::SurfaceId default_surface_id = 370 cc::SurfaceId default_surface_id =
296 window->compositor_frame_sink_manager()->GetLatestSurfaceId( 371 window->compositor_frame_sink_manager()->GetLatestSurfaceId(
297 mojom::CompositorFrameSinkType::DEFAULT); 372 mojom::CompositorFrameSinkType::DEFAULT);
298 if (default_surface_id.is_valid()) 373 if (default_surface_id.is_valid())
299 ReleaseFrameSinkReference(default_surface_id.frame_sink_id()); 374 RemoveFrameSinkReference(default_surface_id.frame_sink_id());
300 375
301 cc::SurfaceId underlay_surface_id = 376 cc::SurfaceId underlay_surface_id =
302 window->compositor_frame_sink_manager()->GetLatestSurfaceId( 377 window->compositor_frame_sink_manager()->GetLatestSurfaceId(
303 mojom::CompositorFrameSinkType::UNDERLAY); 378 mojom::CompositorFrameSinkType::UNDERLAY);
304 if (underlay_surface_id.is_valid()) 379 if (underlay_surface_id.is_valid())
305 ReleaseFrameSinkReference(underlay_surface_id.frame_sink_id()); 380 RemoveFrameSinkReference(underlay_surface_id.frame_sink_id());
306 } 381 }
307 382
308 } // namespace ws 383 } // namespace ws
309 384
310 } // namespace ui 385 } // namespace ui
OLDNEW
« no previous file with comments | « services/ui/ws/frame_generator.h ('k') | services/ui/ws/platform_display.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698