Chromium Code Reviews| Index: services/ui/ws/window_server.cc |
| diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc |
| index 3b0446dea15217be18930c59287a6f6f4925ca74..23a218849f779633f7dfe2d093d442a6c97c77f4 100644 |
| --- a/services/ui/ws/window_server.cc |
| +++ b/services/ui/ws/window_server.cc |
| @@ -606,6 +606,31 @@ bool WindowServer::IsUserInHighContrastMode(const UserId& user) const { |
| return (iter == high_contrast_mode_.end()) ? false : iter->second; |
| } |
| +void WindowServer::ClaimTemporaryReference(ServerWindow* window, |
| + const cc::SurfaceId& surface_id) { |
| + const ClientSpecificId window_client_id = window->id().client_id; |
| + |
| + // Find the first parent window owned by a different client. Since it is a |
| + // a different client, it will need to have a CompositorFrameSink in order to |
| + // embed |window|. |
| + ServerWindow* current = window->parent(); |
| + while (current && current->id().client_id == window_client_id) |
| + current = current->parent(); |
| + |
| + // The client that embeds |window| is expected to submit a CompositorFrame |
| + // that references |surface_id|. Have the parent claim ownership of the |
| + // temporary reference to |surface_id|. If the parent client crashes before it |
| + // adds a surface reference then the GPU can cleanup temporary references. If |
| + // no parent client embeds |window| then tell the GPU to drop the temporary |
| + // reference immediately. |
| + if (current) { |
| + current->GetOrCreateCompositorFrameSinkManager()->ClaimTemporaryReference( |
| + surface_id); |
| + } else { |
| + display_compositor_->DropTemporaryReference(surface_id); |
| + } |
| +} |
| + |
| ServerWindow* WindowServer::GetRootWindow(const ServerWindow* window) { |
| Display* display = display_manager_->GetDisplayContaining(window); |
| return display ? display->root_window() : nullptr; |
| @@ -770,8 +795,6 @@ void WindowServer::OnTransientWindowRemoved(ServerWindow* window, |
| } |
| void WindowServer::OnGpuServiceInitialized() { |
| - // TODO(kylechar): When gpu channel is removed, this can instead happen |
| - // earlier, after GpuHost::OnInitialized(). |
| delegate_->StartDisplayInit(); |
| } |
| @@ -779,16 +802,25 @@ void WindowServer::OnSurfaceCreated(const cc::SurfaceInfo& surface_info) { |
| WindowId window_id( |
| WindowIdFromTransportId(surface_info.id().frame_sink_id().client_id())); |
| ServerWindow* window = GetWindow(window_id); |
| + |
| // If the window doesn't have a parent then we have nothing to propagate. |
| - if (!window) |
| + if (!window) { |
| + display_compositor_->DropTemporaryReference(surface_info.id()); |
| return; |
| + } |
| - // FrameGenerator will add an appropriate reference for the new surface. |
| DCHECK(display_manager_->GetDisplayContaining(window)); |
| auto* display = display_manager_->GetDisplayContaining(window); |
| if (window == display->GetActiveRootWindow()) { |
| + // FrameGenerator will add an appropriate reference for the new surface. |
| display->platform_display()->GetFrameGenerator()->OnSurfaceCreated( |
| surface_info); |
| + |
| + display->root_window() |
| + ->GetOrCreateCompositorFrameSinkManager() |
| + ->ClaimTemporaryReference(surface_info.id()); |
| + } else { |
| + ClaimTemporaryReference(window, surface_info.id()); |
|
Fady Samuel
2017/03/01 16:07:46
Can't we generalize this to be a single code path
Fady Samuel
2017/03/01 17:08:27
Or at least add a comment explaining why this is a
kylechar
2017/03/01 17:15:23
I'll add a comment with why. The client_id doesn't
|
| } |
| // This is only used for testing to observe that a window has a |