OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "cc/raster/one_copy_tile_task_worker_pool.h" | 5 #include "cc/raster/one_copy_tile_task_worker_pool.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 | 105 |
106 OneCopyTileTaskWorkerPool::StagingBuffer::~StagingBuffer() { | 106 OneCopyTileTaskWorkerPool::StagingBuffer::~StagingBuffer() { |
107 DCHECK_EQ(texture_id, 0u); | 107 DCHECK_EQ(texture_id, 0u); |
108 DCHECK_EQ(image_id, 0u); | 108 DCHECK_EQ(image_id, 0u); |
109 DCHECK_EQ(query_id, 0u); | 109 DCHECK_EQ(query_id, 0u); |
110 } | 110 } |
111 | 111 |
112 void OneCopyTileTaskWorkerPool::StagingBuffer::DestroyGLResources( | 112 void OneCopyTileTaskWorkerPool::StagingBuffer::DestroyGLResources( |
113 gpu::gles2::GLES2Interface* gl) { | 113 gpu::gles2::GLES2Interface* gl) { |
114 if (query_id) { | 114 if (query_id) { |
115 gl->DeleteQueriesEXT(1, &query_id); | 115 if (gl) |
| 116 gl->DeleteQueriesEXT(1, &query_id); |
116 query_id = 0; | 117 query_id = 0; |
117 } | 118 } |
118 if (image_id) { | 119 if (image_id) { |
119 gl->DestroyImageCHROMIUM(image_id); | 120 if (gl) |
| 121 gl->DestroyImageCHROMIUM(image_id); |
120 image_id = 0; | 122 image_id = 0; |
121 } | 123 } |
122 if (texture_id) { | 124 if (texture_id) { |
123 gl->DeleteTextures(1, &texture_id); | 125 if (gl) |
| 126 gl->DeleteTextures(1, &texture_id); |
124 texture_id = 0; | 127 texture_id = 0; |
125 } | 128 } |
126 } | 129 } |
127 | 130 |
128 void OneCopyTileTaskWorkerPool::StagingBuffer::OnMemoryDump( | 131 void OneCopyTileTaskWorkerPool::StagingBuffer::OnMemoryDump( |
129 base::trace_event::ProcessMemoryDump* pmd, | 132 base::trace_event::ProcessMemoryDump* pmd, |
130 ResourceFormat format, | 133 ResourceFormat format, |
131 bool in_free_list) const { | 134 bool in_free_list) const { |
132 if (!gpu_memory_buffer) | 135 if (!gpu_memory_buffer) |
133 return; | 136 return; |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 } | 416 } |
414 | 417 |
415 ContextProvider* context_provider = | 418 ContextProvider* context_provider = |
416 resource_provider_->output_surface()->worker_context_provider(); | 419 resource_provider_->output_surface()->worker_context_provider(); |
417 DCHECK(context_provider); | 420 DCHECK(context_provider); |
418 | 421 |
419 { | 422 { |
420 ContextProvider::ScopedContextLock scoped_context(context_provider); | 423 ContextProvider::ScopedContextLock scoped_context(context_provider); |
421 | 424 |
422 gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); | 425 gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); |
423 DCHECK(gl); | 426 if (gl) { |
| 427 unsigned image_target = resource_provider_->GetImageTextureTarget( |
| 428 resource_provider_->memory_efficient_texture_format()); |
424 | 429 |
425 unsigned image_target = resource_provider_->GetImageTextureTarget( | 430 // Create and bind staging texture. |
426 resource_provider_->memory_efficient_texture_format()); | 431 if (!staging_buffer->texture_id) { |
| 432 gl->GenTextures(1, &staging_buffer->texture_id); |
| 433 gl->BindTexture(image_target, staging_buffer->texture_id); |
| 434 gl->TexParameteri(image_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 435 gl->TexParameteri(image_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 436 gl->TexParameteri(image_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 437 gl->TexParameteri(image_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 438 } else { |
| 439 gl->BindTexture(image_target, staging_buffer->texture_id); |
| 440 } |
427 | 441 |
428 // Create and bind staging texture. | 442 // Create and bind image. |
429 if (!staging_buffer->texture_id) { | 443 if (!staging_buffer->image_id) { |
430 gl->GenTextures(1, &staging_buffer->texture_id); | 444 if (staging_buffer->gpu_memory_buffer) { |
431 gl->BindTexture(image_target, staging_buffer->texture_id); | 445 staging_buffer->image_id = gl->CreateImageCHROMIUM( |
432 gl->TexParameteri(image_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 446 staging_buffer->gpu_memory_buffer->AsClientBuffer(), |
433 gl->TexParameteri(image_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 447 staging_buffer->size.width(), staging_buffer->size.height(), |
434 gl->TexParameteri(image_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 448 GLInternalFormat( |
435 gl->TexParameteri(image_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 449 resource_provider_->memory_efficient_texture_format())); |
436 } else { | 450 gl->BindTexImage2DCHROMIUM(image_target, staging_buffer->image_id); |
437 gl->BindTexture(image_target, staging_buffer->texture_id); | 451 } |
438 } | 452 } else { |
439 | 453 gl->ReleaseTexImage2DCHROMIUM(image_target, staging_buffer->image_id); |
440 // Create and bind image. | |
441 if (!staging_buffer->image_id) { | |
442 if (staging_buffer->gpu_memory_buffer) { | |
443 staging_buffer->image_id = gl->CreateImageCHROMIUM( | |
444 staging_buffer->gpu_memory_buffer->AsClientBuffer(), | |
445 staging_buffer->size.width(), staging_buffer->size.height(), | |
446 GLInternalFormat( | |
447 resource_provider_->memory_efficient_texture_format())); | |
448 gl->BindTexImage2DCHROMIUM(image_target, staging_buffer->image_id); | 454 gl->BindTexImage2DCHROMIUM(image_target, staging_buffer->image_id); |
449 } | 455 } |
450 } else { | |
451 gl->ReleaseTexImage2DCHROMIUM(image_target, staging_buffer->image_id); | |
452 gl->BindTexImage2DCHROMIUM(image_target, staging_buffer->image_id); | |
453 } | |
454 | 456 |
455 // Unbind staging texture. | 457 // Unbind staging texture. |
456 gl->BindTexture(image_target, 0); | 458 gl->BindTexture(image_target, 0); |
457 | 459 |
458 if (resource_provider_->use_sync_query()) { | 460 if (resource_provider_->use_sync_query()) { |
459 if (!staging_buffer->query_id) | 461 if (!staging_buffer->query_id) |
460 gl->GenQueriesEXT(1, &staging_buffer->query_id); | 462 gl->GenQueriesEXT(1, &staging_buffer->query_id); |
461 | 463 |
462 #if defined(OS_CHROMEOS) | 464 #if defined(OS_CHROMEOS) |
463 // TODO(reveman): This avoids a performance problem on some ChromeOS | 465 // TODO(reveman): This avoids a performance problem on some ChromeOS |
464 // devices. This needs to be removed to support native GpuMemoryBuffer | 466 // devices. This needs to be removed to support native GpuMemoryBuffer |
465 // implementations. crbug.com/436314 | 467 // implementations. crbug.com/436314 |
466 gl->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, staging_buffer->query_id); | 468 gl->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, |
| 469 staging_buffer->query_id); |
467 #else | 470 #else |
468 gl->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, | 471 gl->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, |
469 staging_buffer->query_id); | 472 staging_buffer->query_id); |
470 #endif | 473 #endif |
471 } | 474 } |
472 | 475 |
473 int bytes_per_row = | 476 int bytes_per_row = |
474 (BitsPerPixel(resource_provider_->memory_efficient_texture_format()) * | 477 (BitsPerPixel(resource_provider_->memory_efficient_texture_format()) * |
475 resource->size().width()) / | 478 resource->size().width()) / |
476 8; | 479 8; |
477 int chunk_size_in_rows = | 480 int chunk_size_in_rows = |
478 std::max(1, max_bytes_per_copy_operation_ / bytes_per_row); | 481 std::max(1, max_bytes_per_copy_operation_ / bytes_per_row); |
479 // Align chunk size to 4. Required to support compressed texture formats. | 482 // Align chunk size to 4. Required to support compressed texture formats. |
(...skipping 24 matching lines...) Expand all Loading... |
504 if (resource_provider_->use_sync_query()) { | 507 if (resource_provider_->use_sync_query()) { |
505 #if defined(OS_CHROMEOS) | 508 #if defined(OS_CHROMEOS) |
506 gl->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM); | 509 gl->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM); |
507 #else | 510 #else |
508 gl->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM); | 511 gl->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM); |
509 #endif | 512 #endif |
510 } | 513 } |
511 | 514 |
512 // Barrier to sync worker context output to cc context. | 515 // Barrier to sync worker context output to cc context. |
513 gl->OrderingBarrierCHROMIUM(); | 516 gl->OrderingBarrierCHROMIUM(); |
| 517 } |
514 } | 518 } |
515 | 519 |
516 staging_buffer->last_usage = base::TimeTicks::Now(); | 520 staging_buffer->last_usage = base::TimeTicks::Now(); |
517 busy_buffers_.push_back(staging_buffer.Pass()); | 521 busy_buffers_.push_back(staging_buffer.Pass()); |
518 | 522 |
519 ScheduleReduceMemoryUsage(); | 523 ScheduleReduceMemoryUsage(); |
520 } | 524 } |
521 | 525 |
522 bool OneCopyTileTaskWorkerPool::OnMemoryDump( | 526 bool OneCopyTileTaskWorkerPool::OnMemoryDump( |
523 const base::trace_event::MemoryDumpArgs& args, | 527 const base::trace_event::MemoryDumpArgs& args, |
(...skipping 17 matching lines...) Expand all Loading... |
541 | 545 |
542 scoped_ptr<StagingBuffer> staging_buffer; | 546 scoped_ptr<StagingBuffer> staging_buffer; |
543 | 547 |
544 ContextProvider* context_provider = | 548 ContextProvider* context_provider = |
545 resource_provider_->output_surface()->worker_context_provider(); | 549 resource_provider_->output_surface()->worker_context_provider(); |
546 DCHECK(context_provider); | 550 DCHECK(context_provider); |
547 | 551 |
548 ContextProvider::ScopedContextLock scoped_context(context_provider); | 552 ContextProvider::ScopedContextLock scoped_context(context_provider); |
549 | 553 |
550 gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); | 554 gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); |
551 DCHECK(gl); | 555 if (gl) { |
| 556 // Check if any busy buffers have become available. |
| 557 if (resource_provider_->use_sync_query()) { |
| 558 while (!busy_buffers_.empty()) { |
| 559 if (!CheckForQueryResult(gl, busy_buffers_.front()->query_id)) |
| 560 break; |
552 | 561 |
553 // Check if any busy buffers have become available. | 562 free_buffers_.push_back(busy_buffers_.take_front()); |
554 if (resource_provider_->use_sync_query()) { | 563 } |
555 while (!busy_buffers_.empty()) { | 564 } |
556 if (!CheckForQueryResult(gl, busy_buffers_.front()->query_id)) | 565 |
| 566 // Wait for number of non-free buffers to become less than the limit. |
| 567 while ((buffers_.size() - free_buffers_.size()) >= max_staging_buffers_) { |
| 568 // Stop when there are no more busy buffers to wait for. |
| 569 if (busy_buffers_.empty()) |
557 break; | 570 break; |
558 | 571 |
559 free_buffers_.push_back(busy_buffers_.take_front()); | 572 if (resource_provider_->use_sync_query()) { |
| 573 WaitForQueryResult(gl, busy_buffers_.front()->query_id); |
| 574 free_buffers_.push_back(busy_buffers_.take_front()); |
| 575 } else { |
| 576 // Fall-back to glFinish if CHROMIUM_sync_query is not available. |
| 577 gl->Finish(); |
| 578 while (!busy_buffers_.empty()) |
| 579 free_buffers_.push_back(busy_buffers_.take_front()); |
| 580 } |
560 } | 581 } |
561 } | 582 } |
562 | 583 |
563 // Wait for number of non-free buffers to become less than the limit. | |
564 while ((buffers_.size() - free_buffers_.size()) >= max_staging_buffers_) { | |
565 // Stop when there are no more busy buffers to wait for. | |
566 if (busy_buffers_.empty()) | |
567 break; | |
568 | |
569 if (resource_provider_->use_sync_query()) { | |
570 WaitForQueryResult(gl, busy_buffers_.front()->query_id); | |
571 free_buffers_.push_back(busy_buffers_.take_front()); | |
572 } else { | |
573 // Fall-back to glFinish if CHROMIUM_sync_query is not available. | |
574 gl->Finish(); | |
575 while (!busy_buffers_.empty()) | |
576 free_buffers_.push_back(busy_buffers_.take_front()); | |
577 } | |
578 } | |
579 | |
580 // Find a staging buffer that allows us to perform partial raster when | 584 // Find a staging buffer that allows us to perform partial raster when |
581 // using persistent GpuMemoryBuffers. | 585 // using persistent GpuMemoryBuffers. |
582 if (use_persistent_gpu_memory_buffers_ && previous_content_id) { | 586 if (use_persistent_gpu_memory_buffers_ && previous_content_id) { |
583 StagingBufferDeque::iterator it = | 587 StagingBufferDeque::iterator it = |
584 std::find_if(free_buffers_.begin(), free_buffers_.end(), | 588 std::find_if(free_buffers_.begin(), free_buffers_.end(), |
585 [previous_content_id](const StagingBuffer* buffer) { | 589 [previous_content_id](const StagingBuffer* buffer) { |
586 return buffer->content_id == previous_content_id; | 590 return buffer->content_id == previous_content_id; |
587 }); | 591 }); |
588 if (it != free_buffers_.end()) | 592 if (it != free_buffers_.end()) |
589 staging_buffer = free_buffers_.take(it); | 593 staging_buffer = free_buffers_.take(it); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 lock_.AssertAcquired(); | 681 lock_.AssertAcquired(); |
678 | 682 |
679 ContextProvider* context_provider = | 683 ContextProvider* context_provider = |
680 resource_provider_->output_surface()->worker_context_provider(); | 684 resource_provider_->output_surface()->worker_context_provider(); |
681 DCHECK(context_provider); | 685 DCHECK(context_provider); |
682 | 686 |
683 { | 687 { |
684 ContextProvider::ScopedContextLock scoped_context(context_provider); | 688 ContextProvider::ScopedContextLock scoped_context(context_provider); |
685 | 689 |
686 gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); | 690 gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); |
687 DCHECK(gl); | |
688 | 691 |
689 // Note: Front buffer is guaranteed to be LRU so we can stop releasing | 692 // Note: Front buffer is guaranteed to be LRU so we can stop releasing |
690 // buffers as soon as we find a buffer that has been used since |time|. | 693 // buffers as soon as we find a buffer that has been used since |time|. |
691 while (!free_buffers_.empty()) { | 694 while (!free_buffers_.empty()) { |
692 if (free_buffers_.front()->last_usage > time) | 695 if (free_buffers_.front()->last_usage > time) |
693 return; | 696 return; |
694 | 697 |
695 free_buffers_.front()->DestroyGLResources(gl); | 698 free_buffers_.front()->DestroyGLResources(gl); |
696 buffers_.erase(free_buffers_.front()); | 699 buffers_.erase(free_buffers_.front()); |
697 free_buffers_.take_front(); | 700 free_buffers_.take_front(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 | 748 |
746 staging_state->SetInteger("staging_buffer_count", | 749 staging_state->SetInteger("staging_buffer_count", |
747 static_cast<int>(buffers_.size())); | 750 static_cast<int>(buffers_.size())); |
748 staging_state->SetInteger("busy_count", | 751 staging_state->SetInteger("busy_count", |
749 static_cast<int>(busy_buffers_.size())); | 752 static_cast<int>(busy_buffers_.size())); |
750 staging_state->SetInteger("free_count", | 753 staging_state->SetInteger("free_count", |
751 static_cast<int>(free_buffers_.size())); | 754 static_cast<int>(free_buffers_.size())); |
752 } | 755 } |
753 | 756 |
754 } // namespace cc | 757 } // namespace cc |
OLD | NEW |