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

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

Issue 2632273003: Move ReferencedSurfaceTracker into GpuCompositorFrameSink. (Closed)
Patch Set: Fix iterator invalidation. Created 3 years, 11 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/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> 7 #include <utility>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/containers/adapters.h" 10 #include "base/containers/adapters.h"
(...skipping 14 matching lines...) Expand all
25 FrameGenerator::FrameGenerator(FrameGeneratorDelegate* delegate, 25 FrameGenerator::FrameGenerator(FrameGeneratorDelegate* delegate,
26 ServerWindow* root_window) 26 ServerWindow* root_window)
27 : delegate_(delegate), 27 : delegate_(delegate),
28 root_window_(root_window), 28 root_window_(root_window),
29 binding_(this), 29 binding_(this),
30 weak_factory_(this) { 30 weak_factory_(this) {
31 DCHECK(delegate_); 31 DCHECK(delegate_);
32 } 32 }
33 33
34 FrameGenerator::~FrameGenerator() { 34 FrameGenerator::~FrameGenerator() {
35 // Remove reference from top level root to the display root surface, if one
36 // exists. This will make everything referenced by the display surface
37 // unreachable so it can be garbage collected.
38 if (surface_tracker_.HasValidSurfaceId()) {
39 compositor_frame_sink_->RemoveSurfaceReferences(
40 std::vector<cc::SurfaceReference>{
41 cc::SurfaceReference(root_window_->delegate()->GetRootSurfaceId(),
42 surface_tracker_.current_surface_id())});
43 }
44
45 // Invalidate WeakPtrs now to avoid callbacks back into the 35 // Invalidate WeakPtrs now to avoid callbacks back into the
46 // FrameGenerator during destruction of |compositor_frame_sink_|. 36 // FrameGenerator during destruction of |compositor_frame_sink_|.
47 weak_factory_.InvalidateWeakPtrs(); 37 weak_factory_.InvalidateWeakPtrs();
48 compositor_frame_sink_.reset(); 38 compositor_frame_sink_.reset();
49 } 39 }
50 40
51 void FrameGenerator::OnAcceleratedWidgetAvailable( 41 void FrameGenerator::OnAcceleratedWidgetAvailable(
52 gfx::AcceleratedWidget widget) { 42 gfx::AcceleratedWidget widget) {
53 DCHECK_NE(gfx::kNullAcceleratedWidget, widget); 43 DCHECK_NE(gfx::kNullAcceleratedWidget, widget);
54 cc::mojom::MojoCompositorFrameSinkRequest request(&compositor_frame_sink_); 44 cc::mojom::MojoCompositorFrameSinkRequest request(&compositor_frame_sink_);
55 cc::mojom::DisplayPrivateRequest display_private_request(&display_private_); 45 cc::mojom::DisplayPrivateRequest display_private_request(&display_private_);
56 root_window_->CreateDisplayCompositorFrameSink( 46 root_window_->CreateDisplayCompositorFrameSink(
57 widget, std::move(request), binding_.CreateInterfacePtrAndBind(), 47 widget, std::move(request), binding_.CreateInterfacePtrAndBind(),
58 std::move(display_private_request)); 48 std::move(display_private_request));
59 // 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
60 // 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,
61 // this will not be necessary because FrameGenerator will only need a 51 // this will not be necessary because FrameGenerator will only need a
62 // BeginFrame if the window manager changes. 52 // BeginFrame if the window manager changes.
63 compositor_frame_sink_->SetNeedsBeginFrame(true); 53 compositor_frame_sink_->SetNeedsBeginFrame(true);
64 } 54 }
65 55
66 void FrameGenerator::OnSurfaceCreated(const cc::SurfaceId& surface_id, 56 void FrameGenerator::OnSurfaceCreated(const cc::SurfaceId& surface_id,
67 ServerWindow* window) { 57 ServerWindow* window) {
68 DCHECK(surface_id.is_valid()); 58 DCHECK(surface_id.is_valid());
69 59
70 // TODO(samans): Clients are actually embedded in the WM and only the WM is
71 // embedded here. This needs to be fixed.
72
73 // Only handle embedded surfaces changing here. The display root surface 60 // Only handle embedded surfaces changing here. The display root surface
74 // changing is handled immediately after the CompositorFrame is submitted. 61 // changing is handled immediately after the CompositorFrame is submitted.
75 if (window != root_window_) { 62 // TODO(samans): Only tell FrameGenerator about WM surface instead of all
76 // Add observer for window the first time it's seen. 63 // all surfaces.
77 if (surface_tracker_.EmbedSurface(surface_id)) 64 if (window == delegate_->GetActiveRootWindow())
78 Add(window); 65 window_manager_surface_id_ = surface_id;
79 }
80 } 66 }
81 67
82 void FrameGenerator::DidReceiveCompositorFrameAck() {} 68 void FrameGenerator::DidReceiveCompositorFrameAck() {}
83 69
84 void FrameGenerator::OnBeginFrame(const cc::BeginFrameArgs& begin_frame_arags) { 70 void FrameGenerator::OnBeginFrame(const cc::BeginFrameArgs& begin_frame_arags) {
85 if (!root_window_->visible()) 71 if (!root_window_->visible())
86 return; 72 return;
87 73
88 // TODO(fsamuel): We should add a trace for generating a top level frame. 74 // TODO(fsamuel): We should add a trace for generating a top level frame.
89 cc::CompositorFrame frame(GenerateCompositorFrame(root_window_->bounds())); 75 cc::CompositorFrame frame(GenerateCompositorFrame(root_window_->bounds()));
90 76
91 if (compositor_frame_sink_) { 77 if (compositor_frame_sink_) {
92 gfx::Size frame_size = last_submitted_frame_size_; 78 gfx::Size frame_size = last_submitted_frame_size_;
93 if (!frame.render_pass_list.empty()) 79 if (!frame.render_pass_list.empty())
94 frame_size = frame.render_pass_list[0]->output_rect.size(); 80 frame_size = frame.render_pass_list[0]->output_rect.size();
95 81
96 bool display_surface_changed = false; 82 if (!local_frame_id_.is_valid() || frame_size != last_submitted_frame_size_)
97 if (!local_frame_id_.is_valid() ||
98 frame_size != last_submitted_frame_size_) {
99 local_frame_id_ = id_allocator_.GenerateId(); 83 local_frame_id_ = id_allocator_.GenerateId();
100 display_surface_changed = true;
101 } else {
102 // If the display surface is changing then we shouldn't add references
103 // from the old display surface. We want to add references from the new
104 // display surface, this happens after we submit the first CompositorFrame
105 // so the new display surface exists.
106 if (surface_tracker_.HasReferencesToAdd()) {
107 compositor_frame_sink_->AddSurfaceReferences(
108 surface_tracker_.GetReferencesToAdd());
109 }
110 }
111 84
112 compositor_frame_sink_->SubmitCompositorFrame(local_frame_id_, 85 compositor_frame_sink_->SubmitCompositorFrame(local_frame_id_,
113 std::move(frame)); 86 std::move(frame));
114 last_submitted_frame_size_ = frame_size; 87 last_submitted_frame_size_ = frame_size;
115
116 if (display_surface_changed)
117 UpdateDisplaySurfaceId();
118
119 // Remove references to surfaces that are no longer embedded. This has to
120 // happen after the frame is submitted otherwise we could end up deleting
121 // a surface that is still embedded in the last submitted frame.
122 if (surface_tracker_.HasReferencesToRemove()) {
123 compositor_frame_sink_->RemoveSurfaceReferences(
124 surface_tracker_.GetReferencesToRemove());
125 }
126 } 88 }
127 } 89 }
128 90
129 void FrameGenerator::ReclaimResources( 91 void FrameGenerator::ReclaimResources(
130 const cc::ReturnedResourceArray& resources) { 92 const cc::ReturnedResourceArray& resources) {
131 // Nothing to do here because FrameGenerator CompositorFrames don't reference 93 // Nothing to do here because FrameGenerator CompositorFrames don't reference
132 // any resources. 94 // any resources.
133 } 95 }
134 96
135 void FrameGenerator::WillDrawSurface() { 97 void FrameGenerator::WillDrawSurface() {
136 // TODO(fsamuel, staraz): Implement this. 98 // TODO(fsamuel, staraz): Implement this.
137 } 99 }
138 100
139 void FrameGenerator::UpdateDisplaySurfaceId() {
140 // FrameGenerator owns the display root surface and is a bit of a special
141 // case. There is no surface that embeds the display surface, so nothing
142 // would reference it. Instead, a reference from the top level root is added
143 // to mark the display surface as visible. As a result, FrameGenerator is
144 // responsible for maintaining a reference from the top level root to the
145 // display surface, in addition to references from the display surface to
146 // embedded surfaces.
147 const cc::SurfaceId old_surface_id = surface_tracker_.current_surface_id();
148 const cc::SurfaceId new_surface_id(
149 cc::FrameSinkId(WindowIdToTransportId(root_window_->id()), 0),
150 local_frame_id_);
151
152 DCHECK_NE(old_surface_id, new_surface_id);
153
154 // Set new SurfaceId for the display surface. This will add references from
155 // the new display surface to all embedded surfaces.
156 surface_tracker_.SetCurrentSurfaceId(new_surface_id);
157 std::vector<cc::SurfaceReference> references_to_add =
158 surface_tracker_.GetReferencesToAdd();
159
160 // Adds a reference from the top level root to the new display surface.
161 references_to_add.push_back(cc::SurfaceReference(
162 root_window_->delegate()->GetRootSurfaceId(), new_surface_id));
163
164 compositor_frame_sink_->AddSurfaceReferences(references_to_add);
165
166 // Remove the reference from the top level root to the old display surface
167 // after we have added references from the new display surface. Not applicable
168 // for the first display surface.
169 if (old_surface_id.is_valid()) {
170 compositor_frame_sink_->RemoveSurfaceReferences(
171 std::vector<cc::SurfaceReference>{cc::SurfaceReference(
172 root_window_->delegate()->GetRootSurfaceId(), old_surface_id)});
173 }
174 }
175
176 cc::CompositorFrame FrameGenerator::GenerateCompositorFrame( 101 cc::CompositorFrame FrameGenerator::GenerateCompositorFrame(
177 const gfx::Rect& output_rect) { 102 const gfx::Rect& output_rect) {
178 const int render_pass_id = 1; 103 const int render_pass_id = 1;
179 std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create(); 104 std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
180 render_pass->SetNew(render_pass_id, output_rect, output_rect, 105 render_pass->SetNew(render_pass_id, output_rect, output_rect,
181 gfx::Transform()); 106 gfx::Transform());
182 107
183 DrawWindow(render_pass.get(), delegate_->GetActiveRootWindow()); 108 DrawWindow(render_pass.get(), delegate_->GetActiveRootWindow());
184 109
185 cc::CompositorFrame frame; 110 cc::CompositorFrame frame;
186 frame.render_pass_list.push_back(std::move(render_pass)); 111 frame.render_pass_list.push_back(std::move(render_pass));
187 if (delegate_->IsInHighContrastMode()) { 112 if (delegate_->IsInHighContrastMode()) {
188 std::unique_ptr<cc::RenderPass> invert_pass = cc::RenderPass::Create(); 113 std::unique_ptr<cc::RenderPass> invert_pass = cc::RenderPass::Create();
189 invert_pass->SetNew(2, output_rect, output_rect, gfx::Transform()); 114 invert_pass->SetNew(2, output_rect, output_rect, gfx::Transform());
190 cc::SharedQuadState* shared_state = 115 cc::SharedQuadState* shared_state =
191 invert_pass->CreateAndAppendSharedQuadState(); 116 invert_pass->CreateAndAppendSharedQuadState();
192 shared_state->SetAll(gfx::Transform(), output_rect.size(), output_rect, 117 shared_state->SetAll(gfx::Transform(), output_rect.size(), output_rect,
193 output_rect, false, 1.f, SkBlendMode::kSrcOver, 0); 118 output_rect, false, 1.f, SkBlendMode::kSrcOver, 0);
194 auto* quad = invert_pass->CreateAndAppendDrawQuad<cc::RenderPassDrawQuad>(); 119 auto* quad = invert_pass->CreateAndAppendDrawQuad<cc::RenderPassDrawQuad>();
195 render_pass->filters.Append(cc::FilterOperation::CreateInvertFilter(1.f)); 120 render_pass->filters.Append(cc::FilterOperation::CreateInvertFilter(1.f));
196 quad->SetNew(shared_state, output_rect, output_rect, render_pass_id, 121 quad->SetNew(shared_state, output_rect, output_rect, render_pass_id,
197 0 /* mask_resource_id */, gfx::Vector2dF() /* mask_uv_scale */, 122 0 /* mask_resource_id */, gfx::Vector2dF() /* mask_uv_scale */,
198 gfx::Size() /* mask_texture_size */, 123 gfx::Size() /* mask_texture_size */,
199 gfx::Vector2dF() /* filters_scale */, 124 gfx::Vector2dF() /* filters_scale */,
200 gfx::PointF() /* filters_origin */); 125 gfx::PointF() /* filters_origin */);
201 frame.render_pass_list.push_back(std::move(invert_pass)); 126 frame.render_pass_list.push_back(std::move(invert_pass));
202 } 127 }
203 frame.metadata.device_scale_factor = device_scale_factor_; 128 frame.metadata.device_scale_factor = device_scale_factor_;
204 129
130 if (window_manager_surface_id_.is_valid())
131 frame.metadata.referenced_surfaces.push_back(window_manager_surface_id_);
132
205 return frame; 133 return frame;
206 } 134 }
207 135
208 void FrameGenerator::DrawWindow(cc::RenderPass* pass, ServerWindow* window) { 136 void FrameGenerator::DrawWindow(cc::RenderPass* pass, ServerWindow* window) {
209 if (!window || !window->visible()) 137 if (!window || !window->visible())
210 return; 138 return;
211 139
212 if (!window->compositor_frame_sink_manager()) 140 if (!window->compositor_frame_sink_manager())
213 return; 141 return;
214 142
(...skipping 19 matching lines...) Expand all
234 1.0f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting-context_id */); 162 1.0f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting-context_id */);
235 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>(); 163 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
236 quad->SetAll(sqs, bounds_at_origin /* rect */, 164 quad->SetAll(sqs, bounds_at_origin /* rect */,
237 gfx::Rect() /* opaque_rect */, 165 gfx::Rect() /* opaque_rect */,
238 bounds_at_origin /* visible_rect */, true /* needs_blending*/, 166 bounds_at_origin /* visible_rect */, true /* needs_blending*/,
239 default_surface_id); 167 default_surface_id);
240 } 168 }
241 169
242 void FrameGenerator::OnWindowDestroying(ServerWindow* window) { 170 void FrameGenerator::OnWindowDestroying(ServerWindow* window) {
243 Remove(window); 171 Remove(window);
244 ServerWindowCompositorFrameSinkManager* compositor_frame_sink_manager =
245 window->compositor_frame_sink_manager();
246 // If FrameGenerator was observing |window|, then that means it had a
247 // CompositorFrame at some point in time and should have a
248 // ServerWindowCompositorFrameSinkManager.
249 DCHECK(compositor_frame_sink_manager);
250
251 cc::SurfaceId surface_id =
252 window->compositor_frame_sink_manager()->GetLatestSurfaceId();
253 if (surface_id.is_valid())
254 surface_tracker_.UnembedSurface(surface_id.frame_sink_id());
255 } 172 }
256 173
257 } // namespace ws 174 } // namespace ws
258 175
259 } // namespace ui 176 } // 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