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

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

Issue 2453013002: Mus: Remove dependency on ServerWindowCompositorFrameSink from FrameGenerator (Closed)
Patch Set: Rebased 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
« no previous file with comments | « services/ui/ws/frame_generator.h ('k') | services/ui/ws/frame_generator_unittest.cc » ('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"
(...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 Add(window_surface->window()); 251 Add(window);
261 return; 252 return;
262 } 253 }
263 254
264 // We are already holding a reference to this surface so there's no work to do 255 // We are already holding a reference to this surface so there's no work to do
265 // here. 256 // here.
266 if (surface_id.local_frame_id() == it->second.local_frame_id) 257 if (surface_id.local_frame_id() == it->second.local_frame_id)
267 return; 258 return;
268 259
269 // If we have have an existing reference to a surface from the given 260 // If we have have an existing reference to a surface from the given
270 // FrameSink, then we should release the reference, and then add this new 261 // FrameSink, then we should release the reference, and then add this new
271 // reference. This results in a delete and lookup in the map but simplifies 262 // reference. This results in a delete and lookup in the map but simplifies
272 // the code. 263 // the code.
273 ReleaseFrameSinkReference(surface_id.frame_sink_id()); 264 ReleaseFrameSinkReference(surface_id.frame_sink_id());
274 265
275 // This recursion will always terminate. This line is being called because 266 // This recursion will always terminate. This line is being called because
276 // there was a stale surface reference. The stale reference has been released 267 // there was a stale surface reference. The stale reference has been released
277 // in the previous line and cleared from the dependencies_ map. Thus, in the 268 // in the previous line and cleared from the dependencies_ map. Thus, in the
278 // recursive call, we'll enter the second if blcok because the FrameSinkId 269 // recursive call, we'll enter the second if blcok because the FrameSinkId
279 // is no longer referenced in the map. 270 // is no longer referenced in the map.
280 AddOrUpdateSurfaceReference(window_surface); 271 AddOrUpdateSurfaceReference(type, window);
281 } 272 }
282 273
283 void FrameGenerator::ReleaseFrameSinkReference( 274 void FrameGenerator::ReleaseFrameSinkReference(
284 const cc::FrameSinkId& frame_sink_id) { 275 const cc::FrameSinkId& frame_sink_id) {
285 auto it = dependencies_.find(frame_sink_id); 276 auto it = dependencies_.find(frame_sink_id);
286 if (it == dependencies_.end()) 277 if (it == dependencies_.end())
287 return; 278 return;
288 std::vector<uint32_t> sequences; 279 std::vector<uint32_t> sequences;
289 sequences.push_back(it->second.sequence.sequence); 280 sequences.push_back(it->second.sequence.sequence);
290 cc::SurfaceManager* surface_manager = display_compositor_->manager(); 281 cc::SurfaceManager* surface_manager = display_compositor_->manager();
291 surface_manager->DidSatisfySequences(frame_sink_id_, &sequences); 282 surface_manager->DidSatisfySequences(frame_sink_id_, &sequences);
292 dependencies_.erase(it); 283 dependencies_.erase(it);
293 } 284 }
294 285
295 void FrameGenerator::ReleaseAllSurfaceReferences() { 286 void FrameGenerator::ReleaseAllSurfaceReferences() {
296 cc::SurfaceManager* surface_manager = display_compositor_->manager(); 287 cc::SurfaceManager* surface_manager = display_compositor_->manager();
297 std::vector<uint32_t> sequences; 288 std::vector<uint32_t> sequences;
298 for (auto& dependency : dependencies_) 289 for (auto& dependency : dependencies_)
299 sequences.push_back(dependency.second.sequence.sequence); 290 sequences.push_back(dependency.second.sequence.sequence);
300 surface_manager->DidSatisfySequences(frame_sink_id_, &sequences); 291 surface_manager->DidSatisfySequences(frame_sink_id_, &sequences);
301 dependencies_.clear(); 292 dependencies_.clear();
302 } 293 }
303 294
304 void FrameGenerator::OnWindowDestroying(ServerWindow* window) { 295 void FrameGenerator::OnWindowDestroying(ServerWindow* window) {
305 Remove(window); 296 Remove(window);
306 ServerWindowCompositorFrameSinkManager* surface_manager = 297 ServerWindowCompositorFrameSinkManager* compositor_frame_sink_manager =
307 window->compositor_frame_sink_manager(); 298 window->compositor_frame_sink_manager();
308 // If FrameGenerator was observing |window|, then that means it had a surface 299 // If FrameGenerator was observing |window|, then that means it had a
309 // at some point in time and should have a 300 // CompositorFrame at some point in time and should have a
310 // ServerWindowCompositorFrameSinkManager. 301 // ServerWindowCompositorFrameSinkManager.
311 DCHECK(surface_manager); 302 DCHECK(compositor_frame_sink_manager);
312 ServerWindowCompositorFrameSink* default_compositor_frame_sink = 303
313 surface_manager->GetDefaultCompositorFrameSink(); 304 cc::SurfaceId default_surface_id =
314 if (default_compositor_frame_sink) 305 window->compositor_frame_sink_manager()->GetLatestSurfaceId(
315 ReleaseFrameSinkReference(default_compositor_frame_sink->frame_sink_id()); 306 mojom::CompositorFrameSinkType::DEFAULT);
316 ServerWindowCompositorFrameSink* underlay_compositor_frame_sink = 307 if (!default_surface_id.is_null())
317 surface_manager->GetUnderlayCompositorFrameSink(); 308 ReleaseFrameSinkReference(default_surface_id.frame_sink_id());
318 if (underlay_compositor_frame_sink) 309
319 ReleaseFrameSinkReference(underlay_compositor_frame_sink->frame_sink_id()); 310 cc::SurfaceId underlay_surface_id =
311 window->compositor_frame_sink_manager()->GetLatestSurfaceId(
312 mojom::CompositorFrameSinkType::UNDERLAY);
313 if (!underlay_surface_id.is_null())
314 ReleaseFrameSinkReference(underlay_surface_id.frame_sink_id());
320 } 315 }
321 316
322 } // namespace ws 317 } // namespace ws
323 318
324 } // namespace ui 319 } // namespace ui
OLDNEW
« no previous file with comments | « services/ui/ws/frame_generator.h ('k') | services/ui/ws/frame_generator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698