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

Side by Side Diff: gpu/command_buffer/service/in_process_command_buffer.cc

Issue 158133004: gpu: Use a single container for GLInProcessContext share group (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « gpu/command_buffer/service/in_process_command_buffer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "gpu/command_buffer/service/in_process_command_buffer.h" 5 #include "gpu/command_buffer/service/in_process_command_buffer.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <utility> 8 #include <utility>
9 9
10 #include <GLES2/gl2.h> 10 #include <GLES2/gl2.h>
(...skipping 25 matching lines...) Expand all
36 36
37 #if defined(OS_ANDROID) 37 #if defined(OS_ANDROID)
38 #include "gpu/command_buffer/service/stream_texture_manager_in_process_android.h " 38 #include "gpu/command_buffer/service/stream_texture_manager_in_process_android.h "
39 #include "ui/gl/android/surface_texture.h" 39 #include "ui/gl/android/surface_texture.h"
40 #endif 40 #endif
41 41
42 namespace gpu { 42 namespace gpu {
43 43
44 namespace { 44 namespace {
45 45
46 static base::LazyInstance<std::set<InProcessCommandBuffer*> >
47 g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER;
48
49 static bool g_use_virtualized_gl_context = false; 46 static bool g_use_virtualized_gl_context = false;
50 static bool g_uses_explicit_scheduling = false; 47 static bool g_uses_explicit_scheduling = false;
51 static GpuMemoryBufferFactory* g_gpu_memory_buffer_factory = NULL; 48 static GpuMemoryBufferFactory* g_gpu_memory_buffer_factory = NULL;
52 49
53 template <typename T> 50 template <typename T>
54 static void RunTaskWithResult(base::Callback<T(void)> task, 51 static void RunTaskWithResult(base::Callback<T(void)> task,
55 T* result, 52 T* result,
56 base::WaitableEvent* completion) { 53 base::WaitableEvent* completion) {
57 *result = task.Run(); 54 *result = task.Run();
58 completion->Signal(); 55 completion->Signal();
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 ~ScopedEvent() { event_->Signal(); } 241 ~ScopedEvent() { event_->Signal(); }
245 242
246 private: 243 private:
247 base::WaitableEvent* event_; 244 base::WaitableEvent* event_;
248 }; 245 };
249 246
250 } // anonyous namespace 247 } // anonyous namespace
251 248
252 InProcessCommandBuffer::InProcessCommandBuffer() 249 InProcessCommandBuffer::InProcessCommandBuffer()
253 : context_lost_(false), 250 : context_lost_(false),
254 share_group_id_(0),
255 last_put_offset_(-1), 251 last_put_offset_(-1),
256 flush_event_(false, false), 252 flush_event_(false, false),
257 queue_(CreateSchedulerClient()), 253 queue_(CreateSchedulerClient()),
258 gpu_thread_weak_ptr_factory_(this) {} 254 gpu_thread_weak_ptr_factory_(this) {}
259 255
260 InProcessCommandBuffer::~InProcessCommandBuffer() { 256 InProcessCommandBuffer::~InProcessCommandBuffer() {
261 Destroy(); 257 Destroy();
262 } 258 }
263 259
264 bool InProcessCommandBuffer::IsContextLost() {
265 CheckSequencedThread();
266 if (context_lost_ || !command_buffer_) {
267 return true;
268 }
269 CommandBuffer::State state = GetState();
270 return error::IsError(state.error);
271 }
272
273 void InProcessCommandBuffer::OnResizeView(gfx::Size size, float scale_factor) { 260 void InProcessCommandBuffer::OnResizeView(gfx::Size size, float scale_factor) {
274 CheckSequencedThread(); 261 CheckSequencedThread();
275 DCHECK(!surface_->IsOffscreen()); 262 DCHECK(!surface_->IsOffscreen());
276 surface_->Resize(size); 263 surface_->Resize(size);
277 } 264 }
278 265
279 bool InProcessCommandBuffer::MakeCurrent() { 266 bool InProcessCommandBuffer::MakeCurrent() {
280 CheckSequencedThread(); 267 CheckSequencedThread();
281 command_buffer_lock_.AssertAcquired(); 268 command_buffer_lock_.AssertAcquired();
282 269
(...skipping 18 matching lines...) Expand all
301 bool InProcessCommandBuffer::GetBufferChanged(int32 transfer_buffer_id) { 288 bool InProcessCommandBuffer::GetBufferChanged(int32 transfer_buffer_id) {
302 CheckSequencedThread(); 289 CheckSequencedThread();
303 command_buffer_lock_.AssertAcquired(); 290 command_buffer_lock_.AssertAcquired();
304 command_buffer_->SetGetBuffer(transfer_buffer_id); 291 command_buffer_->SetGetBuffer(transfer_buffer_id);
305 return true; 292 return true;
306 } 293 }
307 294
308 bool InProcessCommandBuffer::Initialize( 295 bool InProcessCommandBuffer::Initialize(
309 scoped_refptr<gfx::GLSurface> surface, 296 scoped_refptr<gfx::GLSurface> surface,
310 bool is_offscreen, 297 bool is_offscreen,
311 bool share_resources,
312 gfx::AcceleratedWidget window, 298 gfx::AcceleratedWidget window,
313 const gfx::Size& size, 299 const gfx::Size& size,
314 const std::vector<int32>& attribs, 300 const std::vector<int32>& attribs,
315 gfx::GpuPreference gpu_preference, 301 gfx::GpuPreference gpu_preference,
316 const base::Closure& context_lost_callback, 302 const base::Closure& context_lost_callback,
317 unsigned int share_group_id) { 303 InProcessCommandBuffer* share_group) {
318 304
319 share_resources_ = share_resources;
320 context_lost_callback_ = WrapCallback(context_lost_callback); 305 context_lost_callback_ = WrapCallback(context_lost_callback);
321 share_group_id_ = share_group_id;
322 306
323 if (surface) { 307 if (surface) {
324 // GPU thread must be the same as client thread due to GLSurface not being 308 // GPU thread must be the same as client thread due to GLSurface not being
325 // thread safe. 309 // thread safe.
326 sequence_checker_.reset(new base::SequenceChecker); 310 sequence_checker_.reset(new base::SequenceChecker);
327 surface_ = surface; 311 surface_ = surface;
328 } 312 }
329 313
330 gpu::Capabilities capabilities; 314 gpu::Capabilities capabilities;
331 InitializeOnGpuThreadParams params( 315 InitializeOnGpuThreadParams params(is_offscreen,
332 is_offscreen, window, size, attribs, gpu_preference, &capabilities); 316 window,
317 size,
318 attribs,
319 gpu_preference,
320 &capabilities,
321 share_group);
333 322
334 base::Callback<bool(void)> init_task = 323 base::Callback<bool(void)> init_task =
335 base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread, 324 base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread,
336 base::Unretained(this), 325 base::Unretained(this),
337 params); 326 params);
338 327
339 base::WaitableEvent completion(true, false); 328 base::WaitableEvent completion(true, false);
340 bool result = false; 329 bool result = false;
341 QueueTask( 330 QueueTask(
342 base::Bind(&RunTaskWithResult<bool>, init_task, &result, &completion)); 331 base::Bind(&RunTaskWithResult<bool>, init_task, &result, &completion));
343 completion.Wait(); 332 completion.Wait();
344 333
345 if (result) 334 if (result)
346 capabilities_ = capabilities; 335 capabilities_ = capabilities;
347 return result; 336 return result;
348 } 337 }
349 338
350 bool InProcessCommandBuffer::InitializeOnGpuThread( 339 bool InProcessCommandBuffer::InitializeOnGpuThread(
351 const InitializeOnGpuThreadParams& params) { 340 const InitializeOnGpuThreadParams& params) {
352 CheckSequencedThread(); 341 CheckSequencedThread();
353 gpu_thread_weak_ptr_ = gpu_thread_weak_ptr_factory_.GetWeakPtr(); 342 gpu_thread_weak_ptr_ = gpu_thread_weak_ptr_factory_.GetWeakPtr();
354 // Use one share group for all contexts.
355 CR_DEFINE_STATIC_LOCAL(scoped_refptr<gfx::GLShareGroup>, share_group,
356 (new gfx::GLShareGroup));
357 343
358 DCHECK(params.size.width() >= 0 && params.size.height() >= 0); 344 DCHECK(params.size.width() >= 0 && params.size.height() >= 0);
359 345
360 TransferBufferManager* manager = new TransferBufferManager(); 346 TransferBufferManager* manager = new TransferBufferManager();
361 transfer_buffer_manager_.reset(manager); 347 transfer_buffer_manager_.reset(manager);
362 manager->Initialize(); 348 manager->Initialize();
363 349
364 scoped_ptr<CommandBufferService> command_buffer( 350 scoped_ptr<CommandBufferService> command_buffer(
365 new CommandBufferService(transfer_buffer_manager_.get())); 351 new CommandBufferService(transfer_buffer_manager_.get()));
366 command_buffer->SetPutOffsetChangeCallback(base::Bind( 352 command_buffer->SetPutOffsetChangeCallback(base::Bind(
367 &InProcessCommandBuffer::PumpCommands, gpu_thread_weak_ptr_)); 353 &InProcessCommandBuffer::PumpCommands, gpu_thread_weak_ptr_));
368 command_buffer->SetParseErrorCallback(base::Bind( 354 command_buffer->SetParseErrorCallback(base::Bind(
369 &InProcessCommandBuffer::OnContextLost, gpu_thread_weak_ptr_)); 355 &InProcessCommandBuffer::OnContextLost, gpu_thread_weak_ptr_));
370 356
371 if (!command_buffer->Initialize()) { 357 if (!command_buffer->Initialize()) {
372 LOG(ERROR) << "Could not initialize command buffer."; 358 LOG(ERROR) << "Could not initialize command buffer.";
373 DestroyOnGpuThread(); 359 DestroyOnGpuThread();
374 return false; 360 return false;
375 } 361 }
376 362
377 InProcessCommandBuffer* context_group = NULL; 363 gl_share_group_ = params.context_group
378 364 ? params.context_group->gl_share_group_.get()
379 if (share_resources_ && !g_all_shared_contexts.Get().empty()) { 365 : new gfx::GLShareGroup;
380 DCHECK(share_group_id_);
381 for (std::set<InProcessCommandBuffer*>::iterator it =
382 g_all_shared_contexts.Get().begin();
383 it != g_all_shared_contexts.Get().end();
384 ++it) {
385 if ((*it)->share_group_id_ == share_group_id_) {
386 context_group = *it;
387 DCHECK(context_group->share_resources_);
388 context_lost_ = context_group->IsContextLost();
389 break;
390 }
391 }
392 if (!context_group)
393 share_group = new gfx::GLShareGroup;
394 }
395 366
396 #if defined(OS_ANDROID) 367 #if defined(OS_ANDROID)
397 stream_texture_manager_.reset(new StreamTextureManagerInProcess); 368 stream_texture_manager_.reset(new StreamTextureManagerInProcess);
398 #endif 369 #endif
399 370
400 bool bind_generates_resource = false; 371 bool bind_generates_resource = false;
401 decoder_.reset(gles2::GLES2Decoder::Create( 372 decoder_.reset(gles2::GLES2Decoder::Create(
402 context_group ? context_group->decoder_->GetContextGroup() 373 params.context_group ? params.context_group->decoder_->GetContextGroup()
403 : new gles2::ContextGroup(NULL, 374 : new gles2::ContextGroup(NULL,
404 NULL, 375 NULL,
405 NULL, 376 NULL,
406 NULL, 377 NULL,
407 bind_generates_resource))); 378 bind_generates_resource)));
408 379
409 gpu_scheduler_.reset( 380 gpu_scheduler_.reset(
410 new GpuScheduler(command_buffer.get(), decoder_.get(), decoder_.get())); 381 new GpuScheduler(command_buffer.get(), decoder_.get(), decoder_.get()));
411 command_buffer->SetGetBufferChangeCallback(base::Bind( 382 command_buffer->SetGetBufferChangeCallback(base::Bind(
412 &GpuScheduler::SetGetBuffer, base::Unretained(gpu_scheduler_.get()))); 383 &GpuScheduler::SetGetBuffer, base::Unretained(gpu_scheduler_.get())));
413 command_buffer_ = command_buffer.Pass(); 384 command_buffer_ = command_buffer.Pass();
414 385
415 decoder_->set_engine(gpu_scheduler_.get()); 386 decoder_->set_engine(gpu_scheduler_.get());
416 387
417 if (!surface_) { 388 if (!surface_) {
418 if (params.is_offscreen) 389 if (params.is_offscreen)
419 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(params.size); 390 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(params.size);
420 else 391 else
421 surface_ = gfx::GLSurface::CreateViewGLSurface(params.window); 392 surface_ = gfx::GLSurface::CreateViewGLSurface(params.window);
422 } 393 }
423 394
424 if (!surface_.get()) { 395 if (!surface_.get()) {
425 LOG(ERROR) << "Could not create GLSurface."; 396 LOG(ERROR) << "Could not create GLSurface.";
426 DestroyOnGpuThread(); 397 DestroyOnGpuThread();
427 return false; 398 return false;
428 } 399 }
429 400
430 if (g_use_virtualized_gl_context) { 401 if (g_use_virtualized_gl_context) {
431 context_ = share_group->GetSharedContext(); 402 context_ = gl_share_group_->GetSharedContext();
432 if (!context_.get()) { 403 if (!context_.get()) {
433 context_ = gfx::GLContext::CreateGLContext( 404 context_ = gfx::GLContext::CreateGLContext(
434 share_group.get(), surface_.get(), params.gpu_preference); 405 gl_share_group_.get(), surface_.get(), params.gpu_preference);
435 share_group->SetSharedContext(context_.get()); 406 gl_share_group_->SetSharedContext(context_.get());
436 } 407 }
437 408
438 context_ = new GLContextVirtual( 409 context_ = new GLContextVirtual(
439 share_group.get(), context_.get(), decoder_->AsWeakPtr()); 410 gl_share_group_.get(), context_.get(), decoder_->AsWeakPtr());
440 if (context_->Initialize(surface_.get(), params.gpu_preference)) { 411 if (context_->Initialize(surface_.get(), params.gpu_preference)) {
441 VLOG(1) << "Created virtual GL context."; 412 VLOG(1) << "Created virtual GL context.";
442 } else { 413 } else {
443 context_ = NULL; 414 context_ = NULL;
444 } 415 }
445 } else { 416 } else {
446 context_ = gfx::GLContext::CreateGLContext( 417 context_ = gfx::GLContext::CreateGLContext(
447 share_group.get(), surface_.get(), params.gpu_preference); 418 gl_share_group_.get(), surface_.get(), params.gpu_preference);
448 } 419 }
449 420
450 if (!context_.get()) { 421 if (!context_.get()) {
451 LOG(ERROR) << "Could not create GLContext."; 422 LOG(ERROR) << "Could not create GLContext.";
452 DestroyOnGpuThread(); 423 DestroyOnGpuThread();
453 return false; 424 return false;
454 } 425 }
455 426
456 if (!context_->MakeCurrent(surface_.get())) { 427 if (!context_->MakeCurrent(surface_.get())) {
457 LOG(ERROR) << "Could not make context current."; 428 LOG(ERROR) << "Could not make context current.";
(...skipping 21 matching lines...) Expand all
479 decoder_->GetQueryManager(), 450 decoder_->GetQueryManager(),
480 decoder_->GetCapabilities())); 451 decoder_->GetCapabilities()));
481 452
482 *params.capabilities = gpu_control_->GetCapabilities(); 453 *params.capabilities = gpu_control_->GetCapabilities();
483 454
484 if (!params.is_offscreen) { 455 if (!params.is_offscreen) {
485 decoder_->SetResizeCallback(base::Bind( 456 decoder_->SetResizeCallback(base::Bind(
486 &InProcessCommandBuffer::OnResizeView, gpu_thread_weak_ptr_)); 457 &InProcessCommandBuffer::OnResizeView, gpu_thread_weak_ptr_));
487 } 458 }
488 459
489 if (share_resources_) {
490 g_all_shared_contexts.Pointer()->insert(this);
491 }
492
493 return true; 460 return true;
494 } 461 }
495 462
496 void InProcessCommandBuffer::Destroy() { 463 void InProcessCommandBuffer::Destroy() {
497 CheckSequencedThread(); 464 CheckSequencedThread();
498 465
499 base::WaitableEvent completion(true, false); 466 base::WaitableEvent completion(true, false);
500 bool result = false; 467 bool result = false;
501 base::Callback<bool(void)> destroy_task = base::Bind( 468 base::Callback<bool(void)> destroy_task = base::Bind(
502 &InProcessCommandBuffer::DestroyOnGpuThread, base::Unretained(this)); 469 &InProcessCommandBuffer::DestroyOnGpuThread, base::Unretained(this));
503 QueueTask( 470 QueueTask(
504 base::Bind(&RunTaskWithResult<bool>, destroy_task, &result, &completion)); 471 base::Bind(&RunTaskWithResult<bool>, destroy_task, &result, &completion));
505 completion.Wait(); 472 completion.Wait();
506 } 473 }
507 474
508 bool InProcessCommandBuffer::DestroyOnGpuThread() { 475 bool InProcessCommandBuffer::DestroyOnGpuThread() {
509 CheckSequencedThread(); 476 CheckSequencedThread();
510 gpu_thread_weak_ptr_factory_.InvalidateWeakPtrs(); 477 gpu_thread_weak_ptr_factory_.InvalidateWeakPtrs();
511 command_buffer_.reset(); 478 command_buffer_.reset();
512 // Clean up GL resources if possible. 479 // Clean up GL resources if possible.
513 bool have_context = context_ && context_->MakeCurrent(surface_); 480 bool have_context = context_ && context_->MakeCurrent(surface_);
514 if (decoder_) { 481 if (decoder_) {
515 decoder_->Destroy(have_context); 482 decoder_->Destroy(have_context);
516 decoder_.reset(); 483 decoder_.reset();
517 } 484 }
518 context_ = NULL; 485 context_ = NULL;
519 surface_ = NULL; 486 surface_ = NULL;
487 gl_share_group_ = NULL;
520 #if defined(OS_ANDROID) 488 #if defined(OS_ANDROID)
521 stream_texture_manager_.reset(); 489 stream_texture_manager_.reset();
522 #endif 490 #endif
523 491
524 g_all_shared_contexts.Pointer()->erase(this);
525 return true; 492 return true;
526 } 493 }
527 494
528 void InProcessCommandBuffer::CheckSequencedThread() { 495 void InProcessCommandBuffer::CheckSequencedThread() {
529 DCHECK(!sequence_checker_ || 496 DCHECK(!sequence_checker_ ||
530 sequence_checker_->CalledOnValidSequencedThread()); 497 sequence_checker_->CalledOnValidSequencedThread());
531 } 498 }
532 499
533 void InProcessCommandBuffer::OnContextLost() { 500 void InProcessCommandBuffer::OnContextLost() {
534 CheckSequencedThread(); 501 CheckSequencedThread();
535 if (!context_lost_callback_.is_null()) { 502 if (!context_lost_callback_.is_null()) {
536 context_lost_callback_.Run(); 503 context_lost_callback_.Run();
537 context_lost_callback_.Reset(); 504 context_lost_callback_.Reset();
538 } 505 }
539 506
540 context_lost_ = true; 507 context_lost_ = true;
541 if (share_resources_) {
542 for (std::set<InProcessCommandBuffer*>::iterator it =
543 g_all_shared_contexts.Get().begin();
544 it != g_all_shared_contexts.Get().end();
545 ++it) {
546 (*it)->context_lost_ = true;
no sievers 2014/02/12 01:24:32 glLoseContextCHROMIUM() already propagates the los
547 }
548 }
549 } 508 }
550 509
551 CommandBuffer::State InProcessCommandBuffer::GetStateFast() { 510 CommandBuffer::State InProcessCommandBuffer::GetStateFast() {
552 CheckSequencedThread(); 511 CheckSequencedThread();
553 base::AutoLock lock(state_after_last_flush_lock_); 512 base::AutoLock lock(state_after_last_flush_lock_);
554 if (state_after_last_flush_.generation - last_state_.generation < 0x80000000U) 513 if (state_after_last_flush_.generation - last_state_.generation < 0x80000000U)
555 last_state_ = state_after_last_flush_; 514 last_state_ = state_after_last_flush_;
556 return last_state_; 515 return last_state_;
557 } 516 }
558 517
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 g_gpu_queue.Get().RunTasks(); 800 g_gpu_queue.Get().RunTasks();
842 } 801 }
843 802
844 // static 803 // static
845 void InProcessCommandBuffer::SetGpuMemoryBufferFactory( 804 void InProcessCommandBuffer::SetGpuMemoryBufferFactory(
846 GpuMemoryBufferFactory* factory) { 805 GpuMemoryBufferFactory* factory) {
847 g_gpu_memory_buffer_factory = factory; 806 g_gpu_memory_buffer_factory = factory;
848 } 807 }
849 808
850 } // namespace gpu 809 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/in_process_command_buffer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698