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

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

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

Powered by Google App Engine
This is Rietveld 408576698