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

Side by Side Diff: content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc

Issue 1916923004: Request context sharing via content::ContextProviderCommandBuffer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: sharegroup: . Created 4 years, 7 months 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 5 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
6 6
7 #include "third_party/khronos/GLES2/gl2.h" 7 #include "third_party/khronos/GLES2/gl2.h"
8 #ifndef GL_GLEXT_PROTOTYPES 8 #ifndef GL_GLEXT_PROTOTYPES
9 #define GL_GLEXT_PROTOTYPES 1 9 #define GL_GLEXT_PROTOTYPES 1
10 #endif 10 #endif
(...skipping 21 matching lines...) Expand all
32 #include "gpu/command_buffer/client/transfer_buffer.h" 32 #include "gpu/command_buffer/client/transfer_buffer.h"
33 #include "gpu/command_buffer/common/constants.h" 33 #include "gpu/command_buffer/common/constants.h"
34 #include "gpu/command_buffer/common/gpu_memory_allocation.h" 34 #include "gpu/command_buffer/common/gpu_memory_allocation.h"
35 #include "gpu/command_buffer/common/mailbox.h" 35 #include "gpu/command_buffer/common/mailbox.h"
36 #include "gpu/ipc/client/gpu_channel_host.h" 36 #include "gpu/ipc/client/gpu_channel_host.h"
37 #include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h" 37 #include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h"
38 #include "third_party/skia/include/core/SkTypes.h" 38 #include "third_party/skia/include/core/SkTypes.h"
39 39
40 namespace content { 40 namespace content {
41 41
42 namespace {
43
44 static base::LazyInstance<base::Lock>::Leaky
45 g_default_share_groups_lock = LAZY_INSTANCE_INITIALIZER;
46
47 typedef std::map<
48 gpu::GpuChannelHost*,
49 scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup>>
50 ShareGroupMap;
51 static base::LazyInstance<ShareGroupMap> g_default_share_groups =
52 LAZY_INSTANCE_INITIALIZER;
53
54 scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup>
55 GetDefaultShareGroupForHost(gpu::GpuChannelHost* host) {
56 base::AutoLock lock(g_default_share_groups_lock.Get());
57
58 ShareGroupMap& share_groups = g_default_share_groups.Get();
59 ShareGroupMap::iterator it = share_groups.find(host);
60 if (it == share_groups.end()) {
61 scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup> group =
62 new WebGraphicsContext3DCommandBufferImpl::ShareGroup();
63 share_groups[host] = group;
64 return group;
65 }
66 return it->second;
67 }
68
69 } // namespace anonymous
70
71 WebGraphicsContext3DCommandBufferImpl::ShareGroup::ShareGroup() {
72 }
73
74 WebGraphicsContext3DCommandBufferImpl::ShareGroup::~ShareGroup() {
75 DCHECK(contexts_.empty());
76 }
77
78 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( 42 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
79 gpu::SurfaceHandle surface_handle, 43 gpu::SurfaceHandle surface_handle,
80 const GURL& active_url, 44 const GURL& active_url,
81 gpu::GpuChannelHost* host, 45 gpu::GpuChannelHost* host,
82 const gpu::gles2::ContextCreationAttribHelper& attributes, 46 const gpu::gles2::ContextCreationAttribHelper& attributes,
83 gfx::GpuPreference gpu_preference, 47 gfx::GpuPreference gpu_preference,
84 bool share_resources, 48 bool automatic_flushes)
85 bool automatic_flushes,
86 WebGraphicsContext3DCommandBufferImpl* share_context)
87 : automatic_flushes_(automatic_flushes), 49 : automatic_flushes_(automatic_flushes),
88 attributes_(attributes), 50 attributes_(attributes),
89 host_(host), 51 host_(host),
90 surface_handle_(surface_handle), 52 surface_handle_(surface_handle),
91 active_url_(active_url), 53 active_url_(active_url),
92 gpu_preference_(gpu_preference), 54 gpu_preference_(gpu_preference),
93 weak_ptr_factory_(this) { 55 weak_ptr_factory_(this) {
94 DCHECK(host); 56 DCHECK(host);
95 switch (attributes.context_type) { 57 switch (attributes.context_type) {
96 case gpu::gles2::CONTEXT_TYPE_OPENGLES2: 58 case gpu::gles2::CONTEXT_TYPE_OPENGLES2:
97 case gpu::gles2::CONTEXT_TYPE_OPENGLES3: 59 case gpu::gles2::CONTEXT_TYPE_OPENGLES3:
98 context_type_ = CONTEXT_TYPE_UNKNOWN; 60 context_type_ = CONTEXT_TYPE_UNKNOWN;
99 case gpu::gles2::CONTEXT_TYPE_WEBGL1: 61 case gpu::gles2::CONTEXT_TYPE_WEBGL1:
100 case gpu::gles2::CONTEXT_TYPE_WEBGL2: 62 case gpu::gles2::CONTEXT_TYPE_WEBGL2:
101 context_type_ = OFFSCREEN_CONTEXT_FOR_WEBGL; 63 context_type_ = OFFSCREEN_CONTEXT_FOR_WEBGL;
102 } 64 }
103 if (share_context) {
104 DCHECK(!share_resources);
105 share_group_ = share_context->share_group_;
106 } else if (share_resources) {
107 share_group_ = GetDefaultShareGroupForHost(host);
108 } else {
109 share_group_ = make_scoped_refptr(new ShareGroup);
110 }
111 } 65 }
112 66
113 WebGraphicsContext3DCommandBufferImpl:: 67 WebGraphicsContext3DCommandBufferImpl::
114 ~WebGraphicsContext3DCommandBufferImpl() { 68 ~WebGraphicsContext3DCommandBufferImpl() {
115 if (real_gl_) 69 if (real_gl_)
116 real_gl_->SetLostContextCallback(base::Closure()); 70 real_gl_->SetLostContextCallback(base::Closure());
117 71
118 Destroy(); 72 Destroy();
119 } 73 }
120 74
121 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL( 75 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL(
122 const gpu::SharedMemoryLimits& memory_limits) { 76 const gpu::SharedMemoryLimits& memory_limits,
77 gpu::CommandBufferProxyImpl* shared_command_buffer,
78 scoped_refptr<gpu::gles2::ShareGroup> share_group) {
123 if (initialized_) 79 if (initialized_)
124 return true; 80 return true;
125 81
126 if (initialize_failed_) 82 if (initialize_failed_)
127 return false; 83 return false;
128 84
129 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL"); 85 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL");
130 86
131 // TODO(vadimt): Remove ScopedTracker below once crbug.com/125248 is fixed. 87 // TODO(vadimt): Remove ScopedTracker below once crbug.com/125248 is fixed.
132 tracked_objects::ScopedTracker tracking_profile( 88 tracked_objects::ScopedTracker tracking_profile(
133 FROM_HERE_WITH_EXPLICIT_FUNCTION( 89 FROM_HERE_WITH_EXPLICIT_FUNCTION(
134 "125248 WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL")); 90 "125248 WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL"));
135 91
136 if (!CreateContext(memory_limits)) { 92 if (!CreateContext(memory_limits, shared_command_buffer, share_group)) {
piman 2016/04/27 22:09:33 nit: std::move(share_group)
danakj 2016/04/28 00:25:58 Done.
137 Destroy(); 93 Destroy();
138 94
139 initialize_failed_ = true; 95 initialize_failed_ = true;
140 return false; 96 return false;
141 } 97 }
142 98
143 real_gl_->SetLostContextCallback( 99 real_gl_->SetLostContextCallback(
144 base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnContextLost, 100 base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnContextLost,
145 // The callback is unset in the destructor. 101 // The callback is unset in the destructor.
146 base::Unretained(this))); 102 base::Unretained(this)));
147 103
148 real_gl_->TraceBeginCHROMIUM("WebGraphicsContext3D", 104 real_gl_->TraceBeginCHROMIUM("WebGraphicsContext3D",
149 "CommandBufferContext"); 105 "CommandBufferContext");
150 106
151 initialized_ = true; 107 initialized_ = true;
152 return true; 108 return true;
153 } 109 }
154 110
155 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( 111 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer(
156 WebGraphicsContext3DCommandBufferImpl* share_context) { 112 gpu::CommandBufferProxyImpl* shared_command_buffer) {
157 if (!host_.get()) 113 if (!host_.get())
158 return false; 114 return false;
159 115
160 gpu::CommandBufferProxyImpl* share_group_command_buffer = NULL;
161
162 if (share_context) {
163 share_group_command_buffer = share_context->GetCommandBufferProxy();
164 }
165
166 DCHECK(attributes_.buffer_preserved); 116 DCHECK(attributes_.buffer_preserved);
167 std::vector<int32_t> serialized_attributes; 117 std::vector<int32_t> serialized_attributes;
168 attributes_.Serialize(&serialized_attributes); 118 attributes_.Serialize(&serialized_attributes);
169 119
170 // Create a proxy to a command buffer in the GPU process. 120 // Create a proxy to a command buffer in the GPU process.
171 command_buffer_ = host_->CreateCommandBuffer( 121 command_buffer_ = host_->CreateCommandBuffer(
172 surface_handle_, gfx::Size(), share_group_command_buffer, 122 surface_handle_, gfx::Size(), shared_command_buffer,
173 gpu::GpuChannelHost::kDefaultStreamId, 123 gpu::GpuChannelHost::kDefaultStreamId,
174 gpu::GpuChannelHost::kDefaultStreamPriority, serialized_attributes, 124 gpu::GpuChannelHost::kDefaultStreamPriority, serialized_attributes,
175 active_url_, gpu_preference_); 125 active_url_, gpu_preference_);
176 126
177 if (!command_buffer_) { 127 if (!command_buffer_) {
178 DLOG(ERROR) << "GpuChannelHost failed to create command buffer."; 128 DLOG(ERROR) << "GpuChannelHost failed to create command buffer.";
179 UmaRecordContextInitFailed(context_type_); 129 UmaRecordContextInitFailed(context_type_);
180 return false; 130 return false;
181 } 131 }
182 132
183 DVLOG_IF(1, gpu::error::IsError(command_buffer_->GetLastError())) 133 DVLOG_IF(1, gpu::error::IsError(command_buffer_->GetLastError()))
184 << "Context dead on arrival. Last error: " 134 << "Context dead on arrival. Last error: "
185 << command_buffer_->GetLastError(); 135 << command_buffer_->GetLastError();
186 // Initialize the command buffer. 136 // Initialize the command buffer.
187 bool result = command_buffer_->Initialize(); 137 bool result = command_buffer_->Initialize();
188 LOG_IF(ERROR, !result) << "CommandBufferProxy::Initialize failed."; 138 LOG_IF(ERROR, !result) << "CommandBufferProxy::Initialize failed.";
189 if (!result) 139 if (!result)
190 UmaRecordContextInitFailed(context_type_); 140 UmaRecordContextInitFailed(context_type_);
191 return result; 141 return result;
192 } 142 }
193 143
194 bool WebGraphicsContext3DCommandBufferImpl::CreateContext( 144 bool WebGraphicsContext3DCommandBufferImpl::CreateContext(
195 const gpu::SharedMemoryLimits& memory_limits) { 145 const gpu::SharedMemoryLimits& memory_limits,
146 gpu::CommandBufferProxyImpl* shared_command_buffer,
147 scoped_refptr<gpu::gles2::ShareGroup> share_group) {
196 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::CreateContext"); 148 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::CreateContext");
197 scoped_refptr<gpu::gles2::ShareGroup> gles2_share_group; 149 DCHECK_EQ(!!shared_command_buffer, !!share_group);
198 150
199 std::unique_ptr<base::AutoLock> share_group_lock; 151 if (!InitializeCommandBuffer(shared_command_buffer)) {
200 bool add_to_share_group = false; 152 LOG(ERROR) << "Failed to initialize command buffer.";
201 if (!command_buffer_) { 153 return false;
202 WebGraphicsContext3DCommandBufferImpl* share_context = NULL;
203
204 share_group_lock.reset(new base::AutoLock(share_group_->lock()));
205 share_context = share_group_->GetAnyContextLocked();
206
207 if (!InitializeCommandBuffer(share_context)) {
208 LOG(ERROR) << "Failed to initialize command buffer.";
209 return false;
210 }
211
212 if (share_context)
213 gles2_share_group = share_context->GetImplementation()->share_group();
214
215 add_to_share_group = true;
216 } 154 }
217 155
218 // Create the GLES2 helper, which writes the command buffer protocol. 156 // Create the GLES2 helper, which writes the command buffer protocol.
219 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); 157 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get()));
220 if (!gles2_helper_->Initialize(memory_limits.command_buffer_size)) { 158 if (!gles2_helper_->Initialize(memory_limits.command_buffer_size)) {
221 LOG(ERROR) << "Failed to initialize GLES2CmdHelper."; 159 LOG(ERROR) << "Failed to initialize GLES2CmdHelper.";
222 return false; 160 return false;
223 } 161 }
224 162
225 if (!automatic_flushes_) 163 if (!automatic_flushes_)
226 gles2_helper_->SetAutomaticFlushes(false); 164 gles2_helper_->SetAutomaticFlushes(false);
227 // Create a transfer buffer used to copy resources between the renderer 165 // Create a transfer buffer used to copy resources between the renderer
228 // process and the GPU process. 166 // process and the GPU process.
229 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); 167 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get()));
230 168
231 DCHECK(host_.get()); 169 DCHECK(host_.get());
232 170
233 const bool bind_generates_resource = attributes_.bind_generates_resource; 171 const bool bind_generates_resource = attributes_.bind_generates_resource;
234 const bool lose_context_when_out_of_memory = 172 const bool lose_context_when_out_of_memory =
235 attributes_.lose_context_when_out_of_memory; 173 attributes_.lose_context_when_out_of_memory;
236 const bool support_client_side_arrays = false; 174 const bool support_client_side_arrays = false;
237 175
238 // Create the object exposing the OpenGL API. 176 // Create the object exposing the OpenGL API.
239 real_gl_.reset(new gpu::gles2::GLES2Implementation( 177 real_gl_.reset(new gpu::gles2::GLES2Implementation(
240 gles2_helper_.get(), gles2_share_group.get(), transfer_buffer_.get(), 178 gles2_helper_.get(), std::move(share_group), transfer_buffer_.get(),
241 bind_generates_resource, lose_context_when_out_of_memory, 179 bind_generates_resource, lose_context_when_out_of_memory,
242 support_client_side_arrays, command_buffer_.get())); 180 support_client_side_arrays, command_buffer_.get()));
243 if (!real_gl_->Initialize(memory_limits.start_transfer_buffer_size, 181 if (!real_gl_->Initialize(memory_limits.start_transfer_buffer_size,
244 memory_limits.min_transfer_buffer_size, 182 memory_limits.min_transfer_buffer_size,
245 memory_limits.max_transfer_buffer_size, 183 memory_limits.max_transfer_buffer_size,
246 memory_limits.mapped_memory_reclaim_limit)) { 184 memory_limits.mapped_memory_reclaim_limit)) {
247 LOG(ERROR) << "Failed to initialize GLES2Implementation."; 185 LOG(ERROR) << "Failed to initialize GLES2Implementation.";
248 return false; 186 return false;
249 } 187 }
250 188
251 if (add_to_share_group)
252 share_group_->AddContextLocked(this);
253
254 return true; 189 return true;
255 } 190 }
256 191
257 bool WebGraphicsContext3DCommandBufferImpl::InitializeOnCurrentThread( 192 bool WebGraphicsContext3DCommandBufferImpl::InitializeOnCurrentThread(
258 const gpu::SharedMemoryLimits& memory_limits) { 193 const gpu::SharedMemoryLimits& memory_limits,
259 if (!MaybeInitializeGL(memory_limits)) { 194 gpu::CommandBufferProxyImpl* shared_command_buffer,
195 scoped_refptr<gpu::gles2::ShareGroup> share_group) {
196 if (!MaybeInitializeGL(memory_limits, shared_command_buffer, share_group)) {
piman 2016/04/27 22:09:33 nit: std::move(share_group)
danakj 2016/04/28 00:25:58 Done.
260 DLOG(ERROR) << "Failed to initialize context."; 197 DLOG(ERROR) << "Failed to initialize context.";
261 return false; 198 return false;
262 } 199 }
263 if (gpu::error::IsError(command_buffer_->GetLastError())) { 200 if (gpu::error::IsError(command_buffer_->GetLastError())) {
264 LOG(ERROR) << "Context dead on arrival. Last error: " 201 LOG(ERROR) << "Context dead on arrival. Last error: "
265 << command_buffer_->GetLastError(); 202 << command_buffer_->GetLastError();
266 return false; 203 return false;
267 } 204 }
268 205
269 return true; 206 return true;
270 } 207 }
271 208
272 void WebGraphicsContext3DCommandBufferImpl::Destroy() { 209 void WebGraphicsContext3DCommandBufferImpl::Destroy() {
273 share_group_->RemoveContext(this);
274
275 trace_gl_.reset(); 210 trace_gl_.reset();
276 real_gl_.reset(); 211 real_gl_.reset();
277 transfer_buffer_.reset(); 212 transfer_buffer_.reset();
278 gles2_helper_.reset(); 213 gles2_helper_.reset();
279 real_gl_.reset(); 214 real_gl_.reset();
280 command_buffer_.reset(); 215 command_buffer_.reset();
281 216
282 host_ = nullptr; 217 host_ = nullptr;
283 } 218 }
284 219
285 gpu::ContextSupport* 220 gpu::ContextSupport*
286 WebGraphicsContext3DCommandBufferImpl::GetContextSupport() { 221 WebGraphicsContext3DCommandBufferImpl::GetContextSupport() {
287 return real_gl_.get(); 222 return real_gl_.get();
288 } 223 }
289 224
290 void WebGraphicsContext3DCommandBufferImpl::OnContextLost() { 225 void WebGraphicsContext3DCommandBufferImpl::OnContextLost() {
291 if (context_lost_callback_) 226 if (context_lost_callback_)
292 context_lost_callback_->onContextLost(); 227 context_lost_callback_->onContextLost();
293 228
294 share_group_->RemoveAllContexts();
295
296 DCHECK(host_.get());
297 {
298 base::AutoLock lock(g_default_share_groups_lock.Get());
299 g_default_share_groups.Get().erase(host_.get());
300 }
301
302 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); 229 gpu::CommandBuffer::State state = command_buffer_->GetLastState();
303 UmaRecordContextLost(context_type_, state.error, state.context_lost_reason); 230 UmaRecordContextLost(context_type_, state.error, state.context_lost_reason);
304 } 231 }
305 232
306 } // namespace content 233 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698