OLD | NEW |
---|---|
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 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
230 | 230 |
231 WebGraphicsContext3DCommandBufferImpl:: | 231 WebGraphicsContext3DCommandBufferImpl:: |
232 ~WebGraphicsContext3DCommandBufferImpl() { | 232 ~WebGraphicsContext3DCommandBufferImpl() { |
233 if (real_gl_) { | 233 if (real_gl_) { |
234 real_gl_->SetErrorMessageCallback(NULL); | 234 real_gl_->SetErrorMessageCallback(NULL); |
235 } | 235 } |
236 | 236 |
237 Destroy(); | 237 Destroy(); |
238 } | 238 } |
239 | 239 |
240 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() { | 240 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL( |
241 WebGraphicsContext3DCommandBufferImpl* share_context) { | |
241 if (initialized_) | 242 if (initialized_) |
242 return true; | 243 return true; |
243 | 244 |
244 if (initialize_failed_) | 245 if (initialize_failed_) |
245 return false; | 246 return false; |
246 | 247 |
247 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL"); | 248 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL"); |
248 | 249 |
249 if (!CreateContext(surface_id_ != 0)) { | 250 if (!CreateContext(surface_id_ != 0, share_context)) { |
250 Destroy(); | 251 Destroy(); |
251 initialize_failed_ = true; | 252 initialize_failed_ = true; |
252 return false; | 253 return false; |
253 } | 254 } |
254 | 255 |
255 // TODO(twiz): This code is too fragile in that it assumes that only WebGL | 256 // TODO(twiz): This code is too fragile in that it assumes that only WebGL |
256 // contexts will request noExtensions. | 257 // contexts will request noExtensions. |
257 if (gl_ && attributes_.noExtensions) | 258 if (gl_ && attributes_.noExtensions) |
258 gl_->EnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation"); | 259 gl_->EnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation"); |
259 | 260 |
(...skipping 28 matching lines...) Expand all Loading... | |
288 attributes_.stencil = pvalues[2] > 0; | 289 attributes_.stencil = pvalues[2] > 0; |
289 attributes_.antialias = pvalues[3] > 0; | 290 attributes_.antialias = pvalues[3] > 0; |
290 } | 291 } |
291 | 292 |
292 visible_ = true; | 293 visible_ = true; |
293 initialized_ = true; | 294 initialized_ = true; |
294 return true; | 295 return true; |
295 } | 296 } |
296 | 297 |
297 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( | 298 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( |
298 bool onscreen) { | 299 bool onscreen, WebGraphicsContext3DCommandBufferImpl* share_context) { |
299 if (!host_.get()) | 300 if (!host_.get()) |
300 return false; | 301 return false; |
301 // We need to lock g_all_shared_contexts to ensure that the context we picked | 302 // We need to lock g_all_shared_contexts to ensure that the context we picked |
302 // for our share group isn't deleted. | 303 // for our share group isn't deleted. |
303 // (There's also a lock in our destructor.) | 304 // (There's also a lock in our destructor.) |
304 base::AutoLock lock(g_all_shared_contexts_lock.Get()); | 305 base::AutoLock lock(g_all_shared_contexts_lock.Get()); |
306 | |
305 CommandBufferProxyImpl* share_group = NULL; | 307 CommandBufferProxyImpl* share_group = NULL; |
306 if (attributes_.shareResources) { | 308 |
309 if (share_context) | |
310 share_group = share_context->command_buffer_.get(); | |
311 | |
312 if (attributes_.shareResources && !share_group) { | |
307 ContextMap& all_contexts = g_all_shared_contexts.Get(); | 313 ContextMap& all_contexts = g_all_shared_contexts.Get(); |
308 ContextMap::const_iterator it = all_contexts.find(host_.get()); | 314 ContextMap::const_iterator it = all_contexts.find(host_.get()); |
309 if (it != all_contexts.end()) | 315 if (it != all_contexts.end()) |
310 share_group = it->second->command_buffer_.get(); | 316 share_group = it->second->command_buffer_.get(); |
311 } | 317 } |
312 | 318 |
313 std::vector<int32> attribs; | 319 std::vector<int32> attribs; |
314 attribs.push_back(ALPHA_SIZE); | 320 attribs.push_back(ALPHA_SIZE); |
315 attribs.push_back(attributes_.alpha ? 8 : 0); | 321 attribs.push_back(attributes_.alpha ? 8 : 0); |
316 attribs.push_back(DEPTH_SIZE); | 322 attribs.push_back(DEPTH_SIZE); |
(...skipping 26 matching lines...) Expand all Loading... | |
343 } | 349 } |
344 | 350 |
345 if (!command_buffer_) | 351 if (!command_buffer_) |
346 return false; | 352 return false; |
347 | 353 |
348 // Initialize the command buffer. | 354 // Initialize the command buffer. |
349 return command_buffer_->Initialize(); | 355 return command_buffer_->Initialize(); |
350 } | 356 } |
351 | 357 |
352 bool WebGraphicsContext3DCommandBufferImpl::CreateContext( | 358 bool WebGraphicsContext3DCommandBufferImpl::CreateContext( |
353 bool onscreen) { | 359 bool onscreen, WebGraphicsContext3DCommandBufferImpl* share_context) { |
354 // Ensure the gles2 library is initialized first in a thread safe way. | 360 // Ensure the gles2 library is initialized first in a thread safe way. |
355 g_gles2_initializer.Get(); | 361 g_gles2_initializer.Get(); |
356 | 362 |
357 if (!command_buffer_ && | 363 if (!command_buffer_ && |
358 !InitializeCommandBuffer(onscreen)) { | 364 !InitializeCommandBuffer(onscreen, share_context)) { |
359 return false; | 365 return false; |
360 } | 366 } |
361 | 367 |
362 // Create the GLES2 helper, which writes the command buffer protocol. | 368 // Create the GLES2 helper, which writes the command buffer protocol. |
363 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); | 369 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); |
364 if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size)) | 370 if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size)) |
365 return false; | 371 return false; |
366 | 372 |
367 if (attributes_.noAutomaticFlushes) | 373 if (attributes_.noAutomaticFlushes) |
368 gles2_helper_->SetAutomaticFlushes(false); | 374 gles2_helper_->SetAutomaticFlushes(false); |
369 | 375 |
370 // Create a transfer buffer used to copy resources between the renderer | 376 // Create a transfer buffer used to copy resources between the renderer |
371 // process and the GPU process. | 377 // process and the GPU process. |
372 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); | 378 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); |
373 | 379 |
374 DCHECK(host_.get()); | 380 DCHECK(host_.get()); |
375 scoped_ptr<base::AutoLock> lock; | 381 scoped_ptr<base::AutoLock> lock; |
376 scoped_refptr<gpu::gles2::ShareGroup> share_group; | 382 scoped_refptr<gpu::gles2::ShareGroup> share_group; |
377 if (attributes_.shareResources) { | 383 |
384 if (share_context) | |
385 share_group = share_context->GetImplementation()->share_group(); | |
386 | |
387 if (attributes_.shareResources && !share_group) { | |
378 // Make sure two clients don't try to create a new ShareGroup | 388 // Make sure two clients don't try to create a new ShareGroup |
379 // simultaneously. | 389 // simultaneously. |
380 lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get())); | 390 lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get())); |
381 ContextMap& all_contexts = g_all_shared_contexts.Get(); | 391 ContextMap& all_contexts = g_all_shared_contexts.Get(); |
382 ContextMap::const_iterator it = all_contexts.find(host_.get()); | 392 ContextMap::const_iterator it = all_contexts.find(host_.get()); |
383 if (it != all_contexts.end()) { | 393 if (it != all_contexts.end()) { |
384 share_group = it->second->GetImplementation()->share_group(); | 394 share_group = it->second->GetImplementation()->share_group(); |
385 DCHECK(share_group); | 395 DCHECK(share_group); |
386 } | 396 } |
387 } | 397 } |
388 | 398 |
389 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 399 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
390 bool free_command_buffer_when_invisible = | 400 bool free_command_buffer_when_invisible = |
391 command_line.HasSwitch(switches::kEnablePruneGpuCommandBuffers); | 401 command_line.HasSwitch(switches::kEnablePruneGpuCommandBuffers); |
392 | 402 |
393 // Create the object exposing the OpenGL API. | 403 // Create the object exposing the OpenGL API. |
394 real_gl_.reset(new gpu::gles2::GLES2Implementation( | 404 real_gl_.reset(new gpu::gles2::GLES2Implementation( |
395 gles2_helper_.get(), | 405 gles2_helper_.get(), |
396 share_group, | 406 share_group, |
397 transfer_buffer_.get(), | 407 transfer_buffer_.get(), |
398 bind_generates_resources_, | 408 bind_generates_resources_, |
399 free_command_buffer_when_invisible, | 409 free_command_buffer_when_invisible, |
400 command_buffer_.get())); | 410 command_buffer_.get())); |
401 gl_ = real_gl_.get(); | 411 gl_ = real_gl_.get(); |
402 | 412 |
403 if (attributes_.shareResources) { | 413 if (attributes_.shareResources) { |
no sievers
2013/12/11 00:36:27
You might want to check '&& !share_context' here a
| |
404 // Don't add ourselves to the list before others can get to our ShareGroup. | 414 // Don't add ourselves to the list before others can get to our ShareGroup. |
405 g_all_shared_contexts.Get().insert(std::make_pair(host_.get(), this)); | 415 g_all_shared_contexts.Get().insert(std::make_pair(host_.get(), this)); |
406 lock.reset(); | 416 lock.reset(); |
407 } | 417 } |
408 | 418 |
409 if (!real_gl_->Initialize( | 419 if (!real_gl_->Initialize( |
410 mem_limits_.start_transfer_buffer_size, | 420 mem_limits_.start_transfer_buffer_size, |
411 mem_limits_.min_transfer_buffer_size, | 421 mem_limits_.min_transfer_buffer_size, |
412 mem_limits_.max_transfer_buffer_size, | 422 mem_limits_.max_transfer_buffer_size, |
413 mem_limits_.mapped_memory_reclaim_limit)) { | 423 mem_limits_.mapped_memory_reclaim_limit)) { |
414 return false; | 424 return false; |
415 } | 425 } |
416 | 426 |
417 if (CommandLine::ForCurrentProcess()->HasSwitch( | 427 if (CommandLine::ForCurrentProcess()->HasSwitch( |
418 switches::kEnableGpuClientTracing)) { | 428 switches::kEnableGpuClientTracing)) { |
419 trace_gl_.reset(new gpu::gles2::GLES2TraceImplementation(gl_)); | 429 trace_gl_.reset(new gpu::gles2::GLES2TraceImplementation(gl_)); |
420 gl_ = trace_gl_.get(); | 430 gl_ = trace_gl_.get(); |
421 } | 431 } |
422 | 432 |
423 return true; | 433 return true; |
424 } | 434 } |
425 | 435 |
426 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() { | 436 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() { |
427 if (!MaybeInitializeGL()) | 437 if (!MaybeInitializeGL(NULL)) |
428 return false; | 438 return false; |
429 gles2::SetGLContext(gl_); | 439 gles2::SetGLContext(gl_); |
430 if (command_buffer_->GetLastError() != gpu::error::kNoError) | 440 if (command_buffer_->GetLastError() != gpu::error::kNoError) |
431 return false; | 441 return false; |
432 | 442 |
433 return true; | 443 return true; |
434 } | 444 } |
435 | 445 |
436 uint32_t WebGraphicsContext3DCommandBufferImpl::lastFlushID() { | 446 uint32_t WebGraphicsContext3DCommandBufferImpl::lastFlushID() { |
437 return flush_id_; | 447 return flush_id_; |
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1185 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); | 1195 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); |
1186 return state.error == gpu::error::kLostContext; | 1196 return state.error == gpu::error::kLostContext; |
1187 } | 1197 } |
1188 | 1198 |
1189 // static | 1199 // static |
1190 WebGraphicsContext3DCommandBufferImpl* | 1200 WebGraphicsContext3DCommandBufferImpl* |
1191 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( | 1201 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( |
1192 GpuChannelHost* host, | 1202 GpuChannelHost* host, |
1193 const WebGraphicsContext3D::Attributes& attributes, | 1203 const WebGraphicsContext3D::Attributes& attributes, |
1194 const GURL& active_url, | 1204 const GURL& active_url, |
1195 const SharedMemoryLimits& limits) { | 1205 const SharedMemoryLimits& limits, |
1206 WebGraphicsContext3D* share_context) { | |
1196 if (!host) | 1207 if (!host) |
1197 return NULL; | 1208 return NULL; |
1198 return new WebGraphicsContext3DCommandBufferImpl(0, | 1209 |
1199 active_url, | 1210 WebGraphicsContext3DCommandBufferImpl* context = |
1200 host, | 1211 new WebGraphicsContext3DCommandBufferImpl(0, |
1201 attributes, | 1212 active_url, |
1202 false, | 1213 host, |
1203 limits); | 1214 attributes, |
1215 false, | |
1216 limits); | |
1217 | |
1218 if (context && share_context) { | |
1219 if (!context->MaybeInitializeGL(NULL)) { | |
no sievers
2013/12/10 19:53:34
This can't be done here but has to happen on the t
no sievers
2013/12/11 00:36:27
Can you maybe just pull this out by calling makeCo
| |
1220 delete context; | |
1221 return NULL; | |
1222 } | |
1223 } | |
1224 | |
1225 return context; | |
1204 } | 1226 } |
1205 | 1227 |
1206 DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM, | 1228 DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM, |
1207 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint) | 1229 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint) |
1208 | 1230 |
1209 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT, | 1231 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT, |
1210 WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint) | 1232 WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint) |
1211 | 1233 |
1212 WebGLId WebGraphicsContext3DCommandBufferImpl::createQueryEXT() { | 1234 WebGLId WebGraphicsContext3DCommandBufferImpl::createQueryEXT() { |
1213 GLuint o; | 1235 GLuint o; |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1374 | 1396 |
1375 void WebGraphicsContext3DCommandBufferImpl::OnErrorMessage( | 1397 void WebGraphicsContext3DCommandBufferImpl::OnErrorMessage( |
1376 const std::string& message, int id) { | 1398 const std::string& message, int id) { |
1377 if (error_message_callback_) { | 1399 if (error_message_callback_) { |
1378 blink::WebString str = blink::WebString::fromUTF8(message.c_str()); | 1400 blink::WebString str = blink::WebString::fromUTF8(message.c_str()); |
1379 error_message_callback_->onErrorMessage(str, id); | 1401 error_message_callback_->onErrorMessage(str, id); |
1380 } | 1402 } |
1381 } | 1403 } |
1382 | 1404 |
1383 } // namespace content | 1405 } // namespace content |
OLD | NEW |