| OLD | NEW |
| 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 Loading... |
| 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 |
| OLD | NEW |