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 "gpu/command_buffer/service/framebuffer_manager.h" | 5 #include "gpu/command_buffer/service/framebuffer_manager.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 DCHECK(result.second); | 365 DCHECK(result.second); |
366 } | 366 } |
367 | 367 |
368 Framebuffer::Framebuffer( | 368 Framebuffer::Framebuffer( |
369 FramebufferManager* manager, GLuint service_id) | 369 FramebufferManager* manager, GLuint service_id) |
370 : manager_(manager), | 370 : manager_(manager), |
371 deleted_(false), | 371 deleted_(false), |
372 service_id_(service_id), | 372 service_id_(service_id), |
373 has_been_bound_(false), | 373 has_been_bound_(false), |
374 framebuffer_complete_state_count_id_(0), | 374 framebuffer_complete_state_count_id_(0), |
| 375 draw_buffer_type_mask_(0u), |
| 376 draw_buffer_bound_mask_(0u), |
| 377 adjusted_draw_buffer_bound_mask_(0u), |
375 read_buffer_(GL_COLOR_ATTACHMENT0) { | 378 read_buffer_(GL_COLOR_ATTACHMENT0) { |
376 manager->StartTracking(this); | 379 manager->StartTracking(this); |
377 DCHECK_GT(manager->max_draw_buffers_, 0u); | 380 DCHECK_GT(manager->max_draw_buffers_, 0u); |
378 draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]); | 381 draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]); |
| 382 adjusted_draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]); |
379 draw_buffers_[0] = GL_COLOR_ATTACHMENT0; | 383 draw_buffers_[0] = GL_COLOR_ATTACHMENT0; |
380 for (uint32_t i = 1; i < manager->max_draw_buffers_; ++i) | 384 adjusted_draw_buffers_[0] = GL_COLOR_ATTACHMENT0; |
381 draw_buffers_[i] = GL_NONE; | 385 for (uint32_t ii = 1; ii < manager->max_draw_buffers_; ++ii) { |
| 386 draw_buffers_[ii] = GL_NONE; |
| 387 adjusted_draw_buffers_[ii] = GL_NONE; |
| 388 } |
382 } | 389 } |
383 | 390 |
384 Framebuffer::~Framebuffer() { | 391 Framebuffer::~Framebuffer() { |
385 if (manager_) { | 392 if (manager_) { |
386 if (manager_->have_context_) { | 393 if (manager_->have_context_) { |
387 GLuint id = service_id(); | 394 GLuint id = service_id(); |
388 glDeleteFramebuffersEXT(1, &id); | 395 glDeleteFramebuffersEXT(1, &id); |
389 } | 396 } |
390 manager_->StopTracking(this); | 397 manager_->StopTracking(this); |
391 manager_ = NULL; | 398 manager_ = NULL; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 case GL_SRGB_EXT: | 470 case GL_SRGB_EXT: |
464 case GL_SRGB_ALPHA_EXT: | 471 case GL_SRGB_ALPHA_EXT: |
465 return true; | 472 return true; |
466 default: | 473 default: |
467 break; | 474 break; |
468 } | 475 } |
469 } | 476 } |
470 return false; | 477 return false; |
471 } | 478 } |
472 | 479 |
473 bool Framebuffer::PrepareDrawBuffersForClear() const { | 480 bool Framebuffer::PrepareDrawBuffersForClearingUninitializedAttachments( |
| 481 ) const { |
474 std::unique_ptr<GLenum[]> buffers(new GLenum[manager_->max_draw_buffers_]); | 482 std::unique_ptr<GLenum[]> buffers(new GLenum[manager_->max_draw_buffers_]); |
475 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) | 483 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) |
476 buffers[i] = GL_NONE; | 484 buffers[i] = GL_NONE; |
477 for (AttachmentMap::const_iterator it = attachments_.begin(); | 485 for (auto const& it : attachments_) { |
478 it != attachments_.end(); ++it) { | 486 if (it.first >= GL_COLOR_ATTACHMENT0 && |
479 if (it->first >= GL_COLOR_ATTACHMENT0 && | 487 it.first < GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_ && |
480 it->first < GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_ && | 488 !it.second->cleared()) { |
481 !it->second->cleared()) { | |
482 // There should be no partially cleared images, uncleared int/3d images. | 489 // There should be no partially cleared images, uncleared int/3d images. |
483 // This is because ClearUnclearedIntOr3DImagesOrPartiallyClearedImages() | 490 // This is because ClearUnclearedIntOr3DImagesOrPartiallyClearedImages() |
484 // is called before this. | 491 // is called before this. |
485 DCHECK(!GLES2Util::IsIntegerFormat(it->second->internal_format())); | 492 DCHECK(!GLES2Util::IsIntegerFormat(it.second->internal_format())); |
486 DCHECK(!it->second->IsPartiallyCleared()); | 493 DCHECK(!it.second->IsPartiallyCleared()); |
487 DCHECK(!it->second->Is3D()); | 494 DCHECK(!it.second->Is3D()); |
488 buffers[it->first - GL_COLOR_ATTACHMENT0] = it->first; | 495 buffers[it.first - GL_COLOR_ATTACHMENT0] = it.first; |
489 } | 496 } |
490 } | 497 } |
491 bool different = false; | 498 bool different = false; |
492 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) { | 499 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) { |
493 if (buffers[i] != draw_buffers_[i]) { | 500 if (buffers[i] != adjusted_draw_buffers_[i]) { |
494 different = true; | 501 different = true; |
495 break; | 502 break; |
496 } | 503 } |
497 } | 504 } |
498 if (different) | 505 if (different) |
499 glDrawBuffersARB(manager_->max_draw_buffers_, buffers.get()); | 506 glDrawBuffersARB(manager_->max_draw_buffers_, buffers.get()); |
500 return different; | 507 return different; |
501 } | 508 } |
502 | 509 |
503 void Framebuffer::RestoreDrawBuffersAfterClear() const { | 510 void Framebuffer::RestoreDrawBuffers() const { |
504 glDrawBuffersARB(manager_->max_draw_buffers_, draw_buffers_.get()); | 511 glDrawBuffersARB(manager_->max_draw_buffers_, adjusted_draw_buffers_.get()); |
| 512 } |
| 513 |
| 514 bool Framebuffer::ValidateAndAdjustDrawBuffers( |
| 515 uint32_t fragment_output_type_mask, uint32_t fragment_output_written_mask) { |
| 516 uint32_t mask = draw_buffer_bound_mask_ & fragment_output_written_mask; |
| 517 if ((mask & fragment_output_type_mask) != (mask & draw_buffer_type_mask_)) |
| 518 return false; |
| 519 |
| 520 if (mask != adjusted_draw_buffer_bound_mask_) { |
| 521 // This won't be reached in every draw/clear call - only when framebuffer |
| 522 // or program has changed. |
| 523 for (uint32_t ii = 0; ii < manager_->max_draw_buffers_; ++ii) { |
| 524 adjusted_draw_buffers_[ii] = draw_buffers_[ii]; |
| 525 uint32_t shift_bits = ii * 2; |
| 526 uint32_t buffer_mask = 0x3 << shift_bits; |
| 527 if ((buffer_mask & mask) == 0u) { |
| 528 adjusted_draw_buffers_[ii] = GL_NONE; |
| 529 } |
| 530 } |
| 531 adjusted_draw_buffer_bound_mask_ = mask; |
| 532 glDrawBuffersARB(manager_->max_draw_buffers_, adjusted_draw_buffers_.get()); |
| 533 } |
| 534 return true; |
| 535 } |
| 536 |
| 537 bool Framebuffer::ContainsActiveIntegerAttachments() const { |
| 538 // 0x55555555 broadcasts SHADER_VARIABLE_FLOAT to all slots. |
| 539 uint32_t mask = 0x55555555u * SHADER_VARIABLE_FLOAT; |
| 540 mask &= draw_buffer_bound_mask_; |
| 541 return draw_buffer_type_mask_ != mask; |
505 } | 542 } |
506 | 543 |
507 void Framebuffer::ClearUnclearedIntOr3DTexturesOrPartiallyClearedTextures( | 544 void Framebuffer::ClearUnclearedIntOr3DTexturesOrPartiallyClearedTextures( |
508 GLES2Decoder* decoder, | 545 GLES2Decoder* decoder, TextureManager* texture_manager) { |
509 TextureManager* texture_manager) { | |
510 for (AttachmentMap::const_iterator it = attachments_.begin(); | 546 for (AttachmentMap::const_iterator it = attachments_.begin(); |
511 it != attachments_.end(); ++it) { | 547 it != attachments_.end(); ++it) { |
512 if (!it->second->IsTextureAttachment() || it->second->cleared()) | 548 if (!it->second->IsTextureAttachment() || it->second->cleared()) |
513 continue; | 549 continue; |
514 TextureAttachment* attachment = | 550 TextureAttachment* attachment = |
515 reinterpret_cast<TextureAttachment*>(it->second.get()); | 551 reinterpret_cast<TextureAttachment*>(it->second.get()); |
516 if (attachment->IsPartiallyCleared() || attachment->Is3D() || | 552 if (attachment->IsPartiallyCleared() || attachment->Is3D() || |
517 GLES2Util::IsIntegerFormat(attachment->internal_format())) { | 553 GLES2Util::IsIntegerFormat(attachment->internal_format())) { |
518 texture_manager->ClearTextureLevel(decoder, | 554 texture_manager->ClearTextureLevel(decoder, |
519 attachment->texture(), | 555 attachment->texture(), |
520 attachment->target(), | 556 attachment->target(), |
521 attachment->level()); | 557 attachment->level()); |
522 } | 558 } |
523 } | 559 } |
524 } | 560 } |
525 | 561 |
526 void Framebuffer::MarkAttachmentAsCleared( | 562 void Framebuffer::MarkAttachmentAsCleared( |
527 RenderbufferManager* renderbuffer_manager, | 563 RenderbufferManager* renderbuffer_manager, |
528 TextureManager* texture_manager, | 564 TextureManager* texture_manager, |
529 GLenum attachment, | 565 GLenum attachment, |
530 bool cleared) { | 566 bool cleared) { |
531 AttachmentMap::iterator it = attachments_.find(attachment); | 567 AttachmentMap::iterator it = attachments_.find(attachment); |
532 if (it != attachments_.end()) { | 568 if (it != attachments_.end()) { |
533 Attachment* a = it->second.get(); | 569 Attachment* a = it->second.get(); |
534 if (a->cleared() != cleared) { | 570 if (a->cleared() != cleared) { |
535 a->SetCleared(renderbuffer_manager, | 571 a->SetCleared(renderbuffer_manager, |
536 texture_manager, | 572 texture_manager, |
537 cleared); | 573 cleared); |
538 } | 574 } |
539 } | 575 } |
540 } | 576 } |
541 | 577 |
542 void Framebuffer::MarkAttachmentsAsCleared( | 578 void Framebuffer::MarkAttachmentsAsCleared( |
543 RenderbufferManager* renderbuffer_manager, | 579 RenderbufferManager* renderbuffer_manager, |
544 TextureManager* texture_manager, | 580 TextureManager* texture_manager, |
545 bool cleared) { | 581 bool cleared) { |
546 for (AttachmentMap::iterator it = attachments_.begin(); | 582 for (AttachmentMap::iterator it = attachments_.begin(); |
547 it != attachments_.end(); ++it) { | 583 it != attachments_.end(); ++it) { |
548 Attachment* attachment = it->second.get(); | 584 Attachment* attachment = it->second.get(); |
549 if (attachment->cleared() != cleared) { | 585 if (attachment->cleared() != cleared) { |
550 attachment->SetCleared(renderbuffer_manager, texture_manager, cleared); | 586 attachment->SetCleared(renderbuffer_manager, texture_manager, cleared); |
551 } | 587 } |
552 } | 588 } |
553 } | 589 } |
554 | 590 |
555 bool Framebuffer::HasColorAttachment(int index) const { | 591 bool Framebuffer::HasColorAttachment(int index) const { |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 GLenum Framebuffer::GetDrawBuffer(GLenum draw_buffer) const { | 774 GLenum Framebuffer::GetDrawBuffer(GLenum draw_buffer) const { |
739 GLsizei index = static_cast<GLsizei>( | 775 GLsizei index = static_cast<GLsizei>( |
740 draw_buffer - GL_DRAW_BUFFER0_ARB); | 776 draw_buffer - GL_DRAW_BUFFER0_ARB); |
741 CHECK(index >= 0 && | 777 CHECK(index >= 0 && |
742 index < static_cast<GLsizei>(manager_->max_draw_buffers_)); | 778 index < static_cast<GLsizei>(manager_->max_draw_buffers_)); |
743 return draw_buffers_[index]; | 779 return draw_buffers_[index]; |
744 } | 780 } |
745 | 781 |
746 void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) { | 782 void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) { |
747 DCHECK(n <= static_cast<GLsizei>(manager_->max_draw_buffers_)); | 783 DCHECK(n <= static_cast<GLsizei>(manager_->max_draw_buffers_)); |
748 for (GLsizei i = 0; i < n; ++i) | 784 for (GLsizei ii = 0; ii < n; ++ii) { |
749 draw_buffers_[i] = bufs[i]; | 785 draw_buffers_[ii] = bufs[ii]; |
| 786 adjusted_draw_buffers_[ii] = bufs[ii]; |
| 787 } |
| 788 for (uint32_t ii = n; ii < manager_->max_draw_buffers_; ++ii) { |
| 789 draw_buffers_[ii] = GL_NONE; |
| 790 adjusted_draw_buffers_[ii] = GL_NONE; |
| 791 } |
| 792 UpdateDrawBufferMasks(); |
| 793 adjusted_draw_buffer_bound_mask_ = draw_buffer_bound_mask_; |
750 } | 794 } |
751 | 795 |
752 bool Framebuffer::HasAlphaMRT() const { | 796 bool Framebuffer::HasAlphaMRT() const { |
753 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) { | 797 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) { |
754 if (draw_buffers_[i] != GL_NONE) { | 798 if (draw_buffers_[i] != GL_NONE) { |
755 const Attachment* attachment = GetAttachment(draw_buffers_[i]); | 799 const Attachment* attachment = GetAttachment(draw_buffers_[i]); |
756 if (!attachment) | 800 if (!attachment) |
757 continue; | 801 continue; |
758 if ((GLES2Util::GetChannelsForFormat( | 802 if ((GLES2Util::GetChannelsForFormat( |
759 attachment->internal_format()) & 0x0008) != 0) | 803 attachment->internal_format()) & 0x0008) != 0) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 // TODO(gman): manually detach texture. | 855 // TODO(gman): manually detach texture. |
812 // glFramebufferTexture2DEXT(target, it->first, GL_TEXTURE_2D, 0, 0); | 856 // glFramebufferTexture2DEXT(target, it->first, GL_TEXTURE_2D, 0, 0); |
813 AttachTexture(it->first, NULL, GL_TEXTURE_2D, 0, 0); | 857 AttachTexture(it->first, NULL, GL_TEXTURE_2D, 0, 0); |
814 done = false; | 858 done = false; |
815 break; | 859 break; |
816 } | 860 } |
817 } | 861 } |
818 } while (!done); | 862 } while (!done); |
819 } | 863 } |
820 | 864 |
| 865 void Framebuffer::UpdateDrawBufferMasks() { |
| 866 draw_buffer_type_mask_ = 0u; |
| 867 draw_buffer_bound_mask_ = 0u; |
| 868 for (uint32_t index = 0; index < manager_->max_color_attachments_; ++index) { |
| 869 GLenum draw_buffer = draw_buffers_[index]; |
| 870 if (draw_buffer == GL_NONE) |
| 871 continue; |
| 872 auto iter = attachments_.find(draw_buffer); |
| 873 if (iter == attachments_.end()) |
| 874 continue; |
| 875 scoped_refptr<Attachment> attachment = iter->second; |
| 876 GLenum internal_format = attachment->internal_format(); |
| 877 ShaderVariableBaseType base_type = SHADER_VARIABLE_UNDEFINED_TYPE; |
| 878 if (GLES2Util::IsSignedIntegerFormat(internal_format)) { |
| 879 base_type = SHADER_VARIABLE_INT; |
| 880 } else if (GLES2Util::IsUnsignedIntegerFormat(internal_format)) { |
| 881 base_type = SHADER_VARIABLE_UINT; |
| 882 } else { |
| 883 base_type = SHADER_VARIABLE_FLOAT; |
| 884 } |
| 885 size_t shift_bits = index * 2; |
| 886 draw_buffer_type_mask_ |= base_type << shift_bits; |
| 887 draw_buffer_bound_mask_ |= 0x3 << shift_bits; |
| 888 } |
| 889 } |
| 890 |
821 Framebuffer* FramebufferManager::GetFramebuffer( | 891 Framebuffer* FramebufferManager::GetFramebuffer( |
822 GLuint client_id) { | 892 GLuint client_id) { |
823 FramebufferMap::iterator it = framebuffers_.find(client_id); | 893 FramebufferMap::iterator it = framebuffers_.find(client_id); |
824 return it != framebuffers_.end() ? it->second.get() : NULL; | 894 return it != framebuffers_.end() ? it->second.get() : NULL; |
825 } | 895 } |
826 | 896 |
827 void FramebufferManager::RemoveFramebuffer(GLuint client_id) { | 897 void FramebufferManager::RemoveFramebuffer(GLuint client_id) { |
828 FramebufferMap::iterator it = framebuffers_.find(client_id); | 898 FramebufferMap::iterator it = framebuffers_.find(client_id); |
829 if (it != framebuffers_.end()) { | 899 if (it != framebuffers_.end()) { |
830 it->second->MarkAsDeleted(); | 900 it->second->MarkAsDeleted(); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 | 1004 |
935 bool FramebufferManager::IsComplete( | 1005 bool FramebufferManager::IsComplete( |
936 Framebuffer* framebuffer) { | 1006 Framebuffer* framebuffer) { |
937 DCHECK(framebuffer); | 1007 DCHECK(framebuffer); |
938 return framebuffer->framebuffer_complete_state_count_id() == | 1008 return framebuffer->framebuffer_complete_state_count_id() == |
939 framebuffer_state_change_count_; | 1009 framebuffer_state_change_count_; |
940 } | 1010 } |
941 | 1011 |
942 } // namespace gles2 | 1012 } // namespace gles2 |
943 } // namespace gpu | 1013 } // namespace gpu |
OLD | NEW |