OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/android/blimp/chrome_compositor_dependencies.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/command_line.h" | |
9 #include "cc/output/context_provider.h" | |
10 #include "content/public/common/content_switches.h" | |
11 #include "gpu/command_buffer/client/gles2_interface.h" | |
12 #include "gpu/command_buffer/client/shared_memory_limits.h" | |
13 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | |
14 #include "gpu/ipc/client/gpu_channel_host.h" | |
15 | |
16 namespace { | |
17 | |
18 bool IsValidWorkerContext(cc::ContextProvider* context_provider) { | |
19 cc::ContextProvider::ScopedContextLock lock(context_provider); | |
20 return context_provider->ContextGL()->GetGraphicsResetStatusKHR() == | |
21 GL_NO_ERROR; | |
22 } | |
23 | |
24 gpu::gles2::ContextCreationAttribHelper | |
25 GetOffscreenContextCreationAttributes() { | |
26 gpu::gles2::ContextCreationAttribHelper attributes; | |
27 attributes.alpha_size = -1; | |
28 attributes.depth_size = 0; | |
29 attributes.stencil_size = 0; | |
30 attributes.samples = 0; | |
31 attributes.sample_buffers = 0; | |
32 attributes.bind_generates_resource = false; | |
33 attributes.lose_context_when_out_of_memory = true; | |
34 return attributes; | |
35 } | |
36 | |
37 bool IsAsyncWorkerContextEnabled() { | |
38 const base::CommandLine& command_line = | |
39 *base::CommandLine::ForCurrentProcess(); | |
40 | |
41 if (command_line.HasSwitch(switches::kDisableGpuAsyncWorkerContext)) | |
42 return false; | |
43 else if (command_line.HasSwitch(switches::kEnableGpuAsyncWorkerContext)) | |
44 return true; | |
45 | |
46 return false; | |
47 } | |
48 | |
49 } // namespace | |
50 | |
51 ChromeCompositorDependencies::ChromeCompositorDependencies( | |
52 ui::ContextProviderFactory* context_provider_factory) | |
53 : context_provider_factory_(context_provider_factory), weak_factory_(this) { | |
54 DCHECK(context_provider_factory_); | |
55 } | |
56 | |
57 ChromeCompositorDependencies::~ChromeCompositorDependencies() = default; | |
58 | |
59 gpu::GpuMemoryBufferManager* | |
60 ChromeCompositorDependencies::GetGpuMemoryBufferManager() { | |
61 return context_provider_factory_->GetGpuMemoryBufferManager(); | |
62 } | |
63 | |
64 cc::SurfaceManager* ChromeCompositorDependencies::GetSurfaceManager() { | |
65 return context_provider_factory_->GetSurfaceManager(); | |
66 } | |
67 | |
68 cc::FrameSinkId ChromeCompositorDependencies::AllocateFrameSinkId() { | |
69 return context_provider_factory_->AllocateFrameSinkId(); | |
70 } | |
71 | |
72 void ChromeCompositorDependencies::GetContextProviders( | |
73 const ContextProviderCallback& callback) { | |
74 context_provider_factory_->RequestGpuChannelHost( | |
75 base::Bind(&ChromeCompositorDependencies::OnGpuChannelEstablished, | |
76 weak_factory_.GetWeakPtr(), callback)); | |
77 } | |
78 | |
79 void ChromeCompositorDependencies::OnGpuChannelEstablished( | |
80 const ContextProviderCallback& callback, | |
81 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, | |
82 ui::ContextProviderFactory::GpuChannelHostResult result) { | |
83 using GpuRequestResult = ui::ContextProviderFactory::GpuChannelHostResult; | |
84 | |
85 switch (result) { | |
86 case GpuRequestResult::FAILURE_GPU_PROCESS_INITIALIZATION_FAILED: | |
87 // Pass the null result to the caller and let them try again. | |
88 break; | |
89 case GpuRequestResult::FAILURE_FACTORY_SHUTDOWN: | |
90 // If the factory is shutting down, early out and drop the requests. | |
91 return; | |
92 case GpuRequestResult::SUCCESS: | |
93 // Create the worker context first if necessary. | |
94 if (!shared_main_thread_worker_context_ || | |
95 !IsValidWorkerContext(shared_main_thread_worker_context_.get())) { | |
96 shared_main_thread_worker_context_ = | |
97 context_provider_factory_->CreateOffscreenContextProvider( | |
98 ui::ContextProviderFactory::ContextType:: | |
99 BLIMP_RENDER_WORKER_CONTEXT, | |
100 gpu::SharedMemoryLimits(), | |
101 GetOffscreenContextCreationAttributes(), | |
102 true /* support_locking */, false /* automatic_flushes */, | |
103 nullptr, gpu_channel_host); | |
104 if (!shared_main_thread_worker_context_->BindToCurrentThread()) { | |
105 shared_main_thread_worker_context_ = nullptr; | |
106 } | |
107 } | |
108 break; | |
109 } | |
110 | |
111 scoped_refptr<cc::ContextProvider> compositor_context_provider; | |
112 if (gpu_channel_host && shared_main_thread_worker_context_) { | |
113 // The compositor context shares resources with the worker context unless | |
114 // the worker is async. | |
115 cc::ContextProvider* shared_context = | |
116 IsAsyncWorkerContextEnabled() | |
117 ? nullptr | |
118 : shared_main_thread_worker_context_.get(); | |
119 | |
120 compositor_context_provider = | |
121 context_provider_factory_->CreateOffscreenContextProvider( | |
122 ui::ContextProviderFactory::ContextType:: | |
123 BLIMP_RENDER_COMPOSITOR_CONTEXT, | |
124 gpu::SharedMemoryLimits::ForMailboxContext(), | |
125 GetOffscreenContextCreationAttributes(), | |
126 false /* support_locking */, false /* automatic_flushes */, | |
127 shared_context, std::move(gpu_channel_host)); | |
128 } | |
129 | |
130 callback.Run(compositor_context_provider, shared_main_thread_worker_context_); | |
131 } | |
OLD | NEW |