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

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

Issue 2453013002: Mus: Remove dependency on ServerWindowCompositorFrameSink from FrameGenerator (Closed)
Patch Set: Addressed comments 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"
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 } 82 }
83 83
84 void FrameGenerator::Draw() { 84 void FrameGenerator::Draw() {
85 if (!delegate_->GetRootWindow()->visible()) 85 if (!delegate_->GetRootWindow()->visible())
86 return; 86 return;
87 87
88 const gfx::Rect output_rect(delegate_->GetViewportMetrics().pixel_size); 88 const gfx::Rect output_rect(delegate_->GetViewportMetrics().pixel_size);
89 dirty_rect_.Intersect(output_rect); 89 dirty_rect_.Intersect(output_rect);
90 // TODO(fsamuel): We should add a trace for generating a top level frame. 90 // TODO(fsamuel): We should add a trace for generating a top level frame.
91 cc::CompositorFrame frame(GenerateCompositorFrame(output_rect)); 91 cc::CompositorFrame frame(GenerateCompositorFrame(output_rect));
92 if (frame.metadata.may_contain_video != may_contain_video_) {
93 may_contain_video_ = frame.metadata.may_contain_video;
94 // TODO(sad): Schedule notifying observers.
95 if (may_contain_video_) {
96 // TODO(sad): Start a timer to reset the bit if no new frame with video
97 // is submitted 'soon'.
98 }
99 }
100 if (compositor_frame_sink_) { 92 if (compositor_frame_sink_) {
101 frame_pending_ = true; 93 frame_pending_ = true;
102 compositor_frame_sink_->SubmitCompositorFrame( 94 compositor_frame_sink_->SubmitCompositorFrame(
103 std::move(frame), 95 std::move(frame),
104 base::Bind(&FrameGenerator::DidDraw, weak_factory_.GetWeakPtr())); 96 base::Bind(&FrameGenerator::DidDraw, weak_factory_.GetWeakPtr()));
105 } 97 }
106 dirty_rect_ = gfx::Rect(); 98 dirty_rect_ = gfx::Rect();
107 } 99 }
108 100
109 void FrameGenerator::DidDraw() { 101 void FrameGenerator::DidDraw() {
110 frame_pending_ = false; 102 frame_pending_ = false;
111 if (!dirty_rect_.IsEmpty()) 103 if (!dirty_rect_.IsEmpty())
112 WantToDraw(); 104 WantToDraw();
113 } 105 }
114 106
115 cc::CompositorFrame FrameGenerator::GenerateCompositorFrame( 107 cc::CompositorFrame FrameGenerator::GenerateCompositorFrame(
116 const gfx::Rect& output_rect) { 108 const gfx::Rect& output_rect) {
117 const cc::RenderPassId render_pass_id(1, 1); 109 const cc::RenderPassId render_pass_id(1, 1);
118 std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create(); 110 std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
119 render_pass->SetNew(render_pass_id, output_rect, dirty_rect_, 111 render_pass->SetNew(render_pass_id, output_rect, dirty_rect_,
120 gfx::Transform()); 112 gfx::Transform());
121 113
122 bool may_contain_video = false;
123 DrawWindowTree(render_pass.get(), delegate_->GetRootWindow(), gfx::Vector2d(), 114 DrawWindowTree(render_pass.get(), delegate_->GetRootWindow(), gfx::Vector2d(),
124 1.0f, &may_contain_video); 115 1.0f);
125 116
126 std::unique_ptr<cc::DelegatedFrameData> frame_data( 117 std::unique_ptr<cc::DelegatedFrameData> frame_data(
127 new cc::DelegatedFrameData); 118 new cc::DelegatedFrameData);
128 frame_data->render_pass_list.push_back(std::move(render_pass)); 119 frame_data->render_pass_list.push_back(std::move(render_pass));
129 if (delegate_->IsInHighContrastMode()) { 120 if (delegate_->IsInHighContrastMode()) {
130 std::unique_ptr<cc::RenderPass> invert_pass = cc::RenderPass::Create(); 121 std::unique_ptr<cc::RenderPass> invert_pass = cc::RenderPass::Create();
131 invert_pass->SetNew(cc::RenderPassId(2, 0), output_rect, dirty_rect_, 122 invert_pass->SetNew(cc::RenderPassId(2, 0), output_rect, dirty_rect_,
132 gfx::Transform()); 123 gfx::Transform());
133 cc::SharedQuadState* shared_state = 124 cc::SharedQuadState* shared_state =
134 invert_pass->CreateAndAppendSharedQuadState(); 125 invert_pass->CreateAndAppendSharedQuadState();
135 shared_state->SetAll(gfx::Transform(), output_rect.size(), output_rect, 126 shared_state->SetAll(gfx::Transform(), output_rect.size(), output_rect,
136 output_rect, false, 1.f, SkXfermode::kSrcOver_Mode, 0); 127 output_rect, false, 1.f, SkXfermode::kSrcOver_Mode, 0);
137 auto* quad = invert_pass->CreateAndAppendDrawQuad<cc::RenderPassDrawQuad>(); 128 auto* quad = invert_pass->CreateAndAppendDrawQuad<cc::RenderPassDrawQuad>();
138 cc::FilterOperations filters; 129 cc::FilterOperations filters;
139 filters.Append(cc::FilterOperation::CreateInvertFilter(1.f)); 130 filters.Append(cc::FilterOperation::CreateInvertFilter(1.f));
140 quad->SetNew(shared_state, output_rect, output_rect, render_pass_id, 131 quad->SetNew(shared_state, output_rect, output_rect, render_pass_id,
141 0 /* mask_resource_id */, gfx::Vector2dF() /* mask_uv_scale */, 132 0 /* mask_resource_id */, gfx::Vector2dF() /* mask_uv_scale */,
142 gfx::Size() /* mask_texture_size */, filters, 133 gfx::Size() /* mask_texture_size */, filters,
143 gfx::Vector2dF() /* filters_scale */, 134 gfx::Vector2dF() /* filters_scale */,
144 gfx::PointF() /* filters_origin */, 135 gfx::PointF() /* filters_origin */,
145 cc::FilterOperations() /* background_filters */); 136 cc::FilterOperations() /* background_filters */);
146 frame_data->render_pass_list.push_back(std::move(invert_pass)); 137 frame_data->render_pass_list.push_back(std::move(invert_pass));
147 } 138 }
148 139
149 cc::CompositorFrame frame; 140 cc::CompositorFrame frame;
150 frame.delegated_frame_data = std::move(frame_data); 141 frame.delegated_frame_data = std::move(frame_data);
151 frame.metadata.may_contain_video = may_contain_video;
152 return frame; 142 return frame;
153 } 143 }
154 144
155 void FrameGenerator::DrawWindowTree( 145 void FrameGenerator::DrawWindowTree(
156 cc::RenderPass* pass, 146 cc::RenderPass* pass,
157 ServerWindow* window, 147 ServerWindow* window,
158 const gfx::Vector2d& parent_to_root_origin_offset, 148 const gfx::Vector2d& parent_to_root_origin_offset,
159 float opacity, 149 float opacity) {
160 bool* may_contain_video) {
161 if (!window->visible()) 150 if (!window->visible())
162 return; 151 return;
163 152
164 ServerWindowCompositorFrameSink* default_compositor_frame_sink =
165 window->compositor_frame_sink_manager()
166 ? window->compositor_frame_sink_manager()
167 ->GetDefaultCompositorFrameSink()
168 : nullptr;
169
170 const gfx::Rect absolute_bounds = 153 const gfx::Rect absolute_bounds =
171 window->bounds() + parent_to_root_origin_offset; 154 window->bounds() + parent_to_root_origin_offset;
172 const ServerWindow::Windows& children = window->children(); 155 const ServerWindow::Windows& children = window->children();
173 const float combined_opacity = opacity * window->opacity(); 156 const float combined_opacity = opacity * window->opacity();
174 for (ServerWindow* child : base::Reversed(children)) { 157 for (ServerWindow* child : base::Reversed(children)) {
175 DrawWindowTree(pass, child, absolute_bounds.OffsetFromOrigin(), 158 DrawWindowTree(pass, child, absolute_bounds.OffsetFromOrigin(),
176 combined_opacity, may_contain_video); 159 combined_opacity);
177 } 160 }
178 161
179 if (!window->compositor_frame_sink_manager() || 162 if (!window->compositor_frame_sink_manager() ||
180 !window->compositor_frame_sink_manager()->ShouldDraw()) 163 !window->compositor_frame_sink_manager()->ShouldDraw())
181 return; 164 return;
182 165
183 ServerWindowCompositorFrameSink* underlay_compositor_frame_sink = 166 cc::SurfaceId underlay_surface_id =
184 window->compositor_frame_sink_manager()->GetUnderlayCompositorFrameSink(); 167 window->compositor_frame_sink_manager()->GetLatestSurfaceId(
185 if (!default_compositor_frame_sink && !underlay_compositor_frame_sink) 168 mojom::CompositorFrameSinkType::UNDERLAY);
169 cc::SurfaceId default_surface_id =
170 window->compositor_frame_sink_manager()->GetLatestSurfaceId(
171 mojom::CompositorFrameSinkType::DEFAULT);
172
173 if (underlay_surface_id.is_null() && default_surface_id.is_null())
186 return; 174 return;
187 175
188 if (default_compositor_frame_sink) { 176 if (!default_surface_id.is_null()) {
189 gfx::Transform quad_to_target_transform; 177 gfx::Transform quad_to_target_transform;
190 quad_to_target_transform.Translate(absolute_bounds.x(), 178 quad_to_target_transform.Translate(absolute_bounds.x(),
191 absolute_bounds.y()); 179 absolute_bounds.y());
192 180
193 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); 181 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
194 182
195 const gfx::Rect bounds_at_origin(window->bounds().size()); 183 const gfx::Rect bounds_at_origin(window->bounds().size());
196 // TODO(fsamuel): These clipping and visible rects are incorrect. They need 184 // TODO(fsamuel): These clipping and visible rects are incorrect. They need
197 // to be populated from CompositorFrame structs. 185 // to be populated from CompositorFrame structs.
198 sqs->SetAll(quad_to_target_transform, 186 sqs->SetAll(quad_to_target_transform,
199 bounds_at_origin.size() /* layer_bounds */, 187 bounds_at_origin.size() /* layer_bounds */,
200 bounds_at_origin /* visible_layer_bounds */, 188 bounds_at_origin /* visible_layer_bounds */,
201 bounds_at_origin /* clip_rect */, false /* is_clipped */, 189 bounds_at_origin /* clip_rect */, false /* is_clipped */,
202 combined_opacity, SkXfermode::kSrcOver_Mode, 190 combined_opacity, SkXfermode::kSrcOver_Mode,
203 0 /* sorting-context_id */); 191 0 /* sorting-context_id */);
204 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>(); 192 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
205 AddOrUpdateSurfaceReference(default_compositor_frame_sink); 193 AddOrUpdateSurfaceReference(mojom::CompositorFrameSinkType::DEFAULT,
194 window);
206 quad->SetAll(sqs, bounds_at_origin /* rect */, 195 quad->SetAll(sqs, bounds_at_origin /* rect */,
207 gfx::Rect() /* opaque_rect */, 196 gfx::Rect() /* opaque_rect */,
208 bounds_at_origin /* visible_rect */, true /* needs_blending*/, 197 bounds_at_origin /* visible_rect */, true /* needs_blending*/,
209 default_compositor_frame_sink->GetSurfaceId()); 198 default_surface_id);
210 if (default_compositor_frame_sink->may_contain_video())
211 *may_contain_video = true;
212 } 199 }
213 if (underlay_compositor_frame_sink) { 200 if (!underlay_surface_id.is_null()) {
214 const gfx::Rect underlay_absolute_bounds = 201 const gfx::Rect underlay_absolute_bounds =
215 absolute_bounds - window->underlay_offset(); 202 absolute_bounds - window->underlay_offset();
216 gfx::Transform quad_to_target_transform; 203 gfx::Transform quad_to_target_transform;
217 quad_to_target_transform.Translate(underlay_absolute_bounds.x(), 204 quad_to_target_transform.Translate(underlay_absolute_bounds.x(),
218 underlay_absolute_bounds.y()); 205 underlay_absolute_bounds.y());
219 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); 206 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
220 const gfx::Rect bounds_at_origin( 207 const gfx::Rect bounds_at_origin(
221 underlay_compositor_frame_sink->last_submitted_frame_size()); 208 window->compositor_frame_sink_manager()->GetLatestFrameSize(
209 mojom::CompositorFrameSinkType::UNDERLAY));
222 sqs->SetAll(quad_to_target_transform, 210 sqs->SetAll(quad_to_target_transform,
223 bounds_at_origin.size() /* layer_bounds */, 211 bounds_at_origin.size() /* layer_bounds */,
224 bounds_at_origin /* visible_layer_bounds */, 212 bounds_at_origin /* visible_layer_bounds */,
225 bounds_at_origin /* clip_rect */, false /* is_clipped */, 213 bounds_at_origin /* clip_rect */, false /* is_clipped */,
226 combined_opacity, SkXfermode::kSrcOver_Mode, 214 combined_opacity, SkXfermode::kSrcOver_Mode,
227 0 /* sorting-context_id */); 215 0 /* sorting-context_id */);
228 216
229 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>(); 217 auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
230 AddOrUpdateSurfaceReference(underlay_compositor_frame_sink); 218 AddOrUpdateSurfaceReference(mojom::CompositorFrameSinkType::UNDERLAY,
219 window);
231 quad->SetAll(sqs, bounds_at_origin /* rect */, 220 quad->SetAll(sqs, bounds_at_origin /* rect */,
232 gfx::Rect() /* opaque_rect */, 221 gfx::Rect() /* opaque_rect */,
233 bounds_at_origin /* visible_rect */, true /* needs_blending*/, 222 bounds_at_origin /* visible_rect */, true /* needs_blending*/,
234 underlay_compositor_frame_sink->GetSurfaceId()); 223 underlay_surface_id);
235 DCHECK(!underlay_compositor_frame_sink->may_contain_video());
236 } 224 }
237 } 225 }
238 226
239 void FrameGenerator::AddOrUpdateSurfaceReference( 227 void FrameGenerator::AddOrUpdateSurfaceReference(
240 ServerWindowCompositorFrameSink* window_surface) { 228 mojom::CompositorFrameSinkType type,
241 if (!window_surface->has_frame()) 229 ServerWindow* window) {
230 cc::SurfaceId surface_id =
231 window->compositor_frame_sink_manager()->GetLatestSurfaceId(type);
232 if (surface_id.is_null())
242 return; 233 return;
243 cc::SurfaceId surface_id = window_surface->GetSurfaceId(); 234 // TODO(fsamuel): Use mojo interface to give root window a surface reference.
244 cc::SurfaceManager* surface_manager = display_compositor_->manager(); 235 cc::SurfaceManager* surface_manager = display_compositor_->manager();
245 auto it = dependencies_.find(surface_id.frame_sink_id()); 236 auto it = dependencies_.find(surface_id.frame_sink_id());
246 if (it == dependencies_.end()) { 237 if (it == dependencies_.end()) {
247 cc::Surface* surface = surface_manager->GetSurfaceForId(surface_id); 238 cc::Surface* surface = surface_manager->GetSurfaceForId(surface_id);
248 if (!surface) { 239 if (!surface) {
249 LOG(ERROR) << "Attempting to add dependency to nonexistent surface " 240 LOG(ERROR) << "Attempting to add dependency to nonexistent surface "
250 << surface_id.ToString(); 241 << surface_id.ToString();
251 return; 242 return;
252 } 243 }
253 SurfaceDependency dependency = { 244 SurfaceDependency dependency = {
254 surface_id.local_frame_id(), 245 surface_id.local_frame_id(),
255 surface_sequence_generator_.CreateSurfaceSequence()}; 246 surface_sequence_generator_.CreateSurfaceSequence()};
256 surface->AddDestructionDependency(dependency.sequence); 247 surface->AddDestructionDependency(dependency.sequence);
257 dependencies_[surface_id.frame_sink_id()] = dependency; 248 dependencies_[surface_id.frame_sink_id()] = dependency;
258 // Observe |window_surface|'s window so that we can release references when 249 // Observe |window_surface|'s window so that we can release references when
259 // the window is destroyed. 250 // the window is destroyed.
260 if (!window_surface->window()->HasObserver(this)) 251 if (!window->HasObserver(this))
261 window_surface->window()->AddObserver(this); 252 window->AddObserver(this);
262 return; 253 return;
263 } 254 }
264 255
265 // We are already holding a reference to this surface so there's no work to do 256 // We are already holding a reference to this surface so there's no work to do
266 // here. 257 // here.
267 if (surface_id.local_frame_id() == it->second.local_frame_id) 258 if (surface_id.local_frame_id() == it->second.local_frame_id)
268 return; 259 return;
269 260
270 // If we have have an existing reference to a surface from the given 261 // If we have have an existing reference to a surface from the given
271 // FrameSink, then we should release the reference, and then add this new 262 // FrameSink, then we should release the reference, and then add this new
272 // reference. This results in a delete and lookup in the map but simplifies 263 // reference. This results in a delete and lookup in the map but simplifies
273 // the code. 264 // the code.
274 ReleaseFrameSinkReference(surface_id.frame_sink_id()); 265 ReleaseFrameSinkReference(surface_id.frame_sink_id());
275 266
276 // This recursion will always terminate. This line is being called because 267 // This recursion will always terminate. This line is being called because
277 // there was a stale surface reference. The stale reference has been released 268 // there was a stale surface reference. The stale reference has been released
278 // in the previous line and cleared from the dependencies_ map. Thus, in the 269 // in the previous line and cleared from the dependencies_ map. Thus, in the
279 // recursive call, we'll enter the second if blcok because the FrameSinkId 270 // recursive call, we'll enter the second if blcok because the FrameSinkId
280 // is no longer referenced in the map. 271 // is no longer referenced in the map.
281 AddOrUpdateSurfaceReference(window_surface); 272 AddOrUpdateSurfaceReference(type, window);
282 } 273 }
283 274
284 void FrameGenerator::ReleaseFrameSinkReference( 275 void FrameGenerator::ReleaseFrameSinkReference(
285 const cc::FrameSinkId& frame_sink_id) { 276 const cc::FrameSinkId& frame_sink_id) {
286 auto it = dependencies_.find(frame_sink_id); 277 auto it = dependencies_.find(frame_sink_id);
287 if (it == dependencies_.end()) 278 if (it == dependencies_.end())
288 return; 279 return;
289 std::vector<uint32_t> sequences; 280 std::vector<uint32_t> sequences;
290 sequences.push_back(it->second.sequence.sequence); 281 sequences.push_back(it->second.sequence.sequence);
291 cc::SurfaceManager* surface_manager = display_compositor_->manager(); 282 cc::SurfaceManager* surface_manager = display_compositor_->manager();
292 surface_manager->DidSatisfySequences(frame_sink_id_, &sequences); 283 surface_manager->DidSatisfySequences(frame_sink_id_, &sequences);
293 dependencies_.erase(it); 284 dependencies_.erase(it);
294 } 285 }
295 286
296 void FrameGenerator::ReleaseAllSurfaceReferences() { 287 void FrameGenerator::ReleaseAllSurfaceReferences() {
297 cc::SurfaceManager* surface_manager = display_compositor_->manager(); 288 cc::SurfaceManager* surface_manager = display_compositor_->manager();
298 std::vector<uint32_t> sequences; 289 std::vector<uint32_t> sequences;
299 for (auto& dependency : dependencies_) 290 for (auto& dependency : dependencies_)
300 sequences.push_back(dependency.second.sequence.sequence); 291 sequences.push_back(dependency.second.sequence.sequence);
301 surface_manager->DidSatisfySequences(frame_sink_id_, &sequences); 292 surface_manager->DidSatisfySequences(frame_sink_id_, &sequences);
302 dependencies_.clear(); 293 dependencies_.clear();
303 } 294 }
304 295
305 void FrameGenerator::OnWindowDestroying(ServerWindow* window) { 296 void FrameGenerator::OnWindowDestroying(ServerWindow* window) {
306 window->RemoveObserver(this); 297 window->RemoveObserver(this);
307 ServerWindowCompositorFrameSinkManager* surface_manager = 298 ServerWindowCompositorFrameSinkManager* compositor_frame_sink_manager =
308 window->compositor_frame_sink_manager(); 299 window->compositor_frame_sink_manager();
309 // If FrameGenerator was observing |window|, then that means it had a surface 300 // If FrameGenerator was observing |window|, then that means it had a
310 // at some point in time and should have a 301 // CompositorFrame at some point in time and should have a
311 // ServerWindowCompositorFrameSinkManager. 302 // ServerWindowCompositorFrameSinkManager.
312 DCHECK(surface_manager); 303 DCHECK(compositor_frame_sink_manager);
313 ServerWindowCompositorFrameSink* default_compositor_frame_sink = 304
314 surface_manager->GetDefaultCompositorFrameSink(); 305 cc::SurfaceId default_surface_id =
315 if (default_compositor_frame_sink) 306 window->compositor_frame_sink_manager()->GetLatestSurfaceId(
316 ReleaseFrameSinkReference(default_compositor_frame_sink->frame_sink_id()); 307 mojom::CompositorFrameSinkType::DEFAULT);
317 ServerWindowCompositorFrameSink* underlay_compositor_frame_sink = 308 if (!default_surface_id.is_null())
318 surface_manager->GetUnderlayCompositorFrameSink(); 309 ReleaseFrameSinkReference(default_surface_id.frame_sink_id());
319 if (underlay_compositor_frame_sink) 310
320 ReleaseFrameSinkReference(underlay_compositor_frame_sink->frame_sink_id()); 311 cc::SurfaceId underlay_surface_id =
312 window->compositor_frame_sink_manager()->GetLatestSurfaceId(
313 mojom::CompositorFrameSinkType::UNDERLAY);
314 if (!underlay_surface_id.is_null())
315 ReleaseFrameSinkReference(underlay_surface_id.frame_sink_id());
321 } 316 }
322 317
323 } // namespace ws 318 } // namespace ws
324 319
325 } // namespace ui 320 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698