Chromium Code Reviews| 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), | |
| 375 read_buffer_(GL_COLOR_ATTACHMENT0) { | 377 read_buffer_(GL_COLOR_ATTACHMENT0) { |
| 376 manager->StartTracking(this); | 378 manager->StartTracking(this); |
| 377 DCHECK_GT(manager->max_draw_buffers_, 0u); | 379 DCHECK_GT(manager->max_draw_buffers_, 0u); |
| 378 draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]); | 380 draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]); |
| 381 adjusted_draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]); | |
| 379 draw_buffers_[0] = GL_COLOR_ATTACHMENT0; | 382 draw_buffers_[0] = GL_COLOR_ATTACHMENT0; |
| 380 for (uint32_t i = 1; i < manager->max_draw_buffers_; ++i) | 383 adjusted_draw_buffers_[0] = GL_COLOR_ATTACHMENT0; |
| 381 draw_buffers_[i] = GL_NONE; | 384 for (uint32_t ii = 1; ii < manager->max_draw_buffers_; ++ii) { |
| 385 draw_buffers_[ii] = GL_NONE; | |
| 386 adjusted_draw_buffers_[ii] = GL_NONE; | |
| 387 } | |
| 382 } | 388 } |
| 383 | 389 |
| 384 Framebuffer::~Framebuffer() { | 390 Framebuffer::~Framebuffer() { |
| 385 if (manager_) { | 391 if (manager_) { |
| 386 if (manager_->have_context_) { | 392 if (manager_->have_context_) { |
| 387 GLuint id = service_id(); | 393 GLuint id = service_id(); |
| 388 glDeleteFramebuffersEXT(1, &id); | 394 glDeleteFramebuffersEXT(1, &id); |
| 389 } | 395 } |
| 390 manager_->StopTracking(this); | 396 manager_->StopTracking(this); |
| 391 manager_ = NULL; | 397 manager_ = NULL; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 463 case GL_SRGB_EXT: | 469 case GL_SRGB_EXT: |
| 464 case GL_SRGB_ALPHA_EXT: | 470 case GL_SRGB_ALPHA_EXT: |
| 465 return true; | 471 return true; |
| 466 default: | 472 default: |
| 467 break; | 473 break; |
| 468 } | 474 } |
| 469 } | 475 } |
| 470 return false; | 476 return false; |
| 471 } | 477 } |
| 472 | 478 |
| 473 bool Framebuffer::PrepareDrawBuffersForClear() const { | 479 bool Framebuffer::PrepareDrawBuffersForClearingUninitializedAttachments( |
| 480 ) const { | |
| 474 std::unique_ptr<GLenum[]> buffers(new GLenum[manager_->max_draw_buffers_]); | 481 std::unique_ptr<GLenum[]> buffers(new GLenum[manager_->max_draw_buffers_]); |
| 475 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) | 482 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) |
| 476 buffers[i] = GL_NONE; | 483 buffers[i] = GL_NONE; |
| 477 for (AttachmentMap::const_iterator it = attachments_.begin(); | 484 for (auto const& it : attachments_) { |
| 478 it != attachments_.end(); ++it) { | 485 if (it.first >= GL_COLOR_ATTACHMENT0 && |
| 479 if (it->first >= GL_COLOR_ATTACHMENT0 && | 486 it.first < GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_ && |
| 480 it->first < GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_ && | 487 !it.second->cleared()) { |
| 481 !it->second->cleared()) { | |
| 482 // There should be no partially cleared images, uncleared int/3d images. | 488 // There should be no partially cleared images, uncleared int/3d images. |
| 483 // This is because ClearUnclearedIntOr3DImagesOrPartiallyClearedImages() | 489 // This is because ClearUnclearedIntOr3DImagesOrPartiallyClearedImages() |
| 484 // is called before this. | 490 // is called before this. |
| 485 DCHECK(!GLES2Util::IsIntegerFormat(it->second->internal_format())); | 491 DCHECK(!GLES2Util::IsIntegerFormat(it.second->internal_format())); |
| 486 DCHECK(!it->second->IsPartiallyCleared()); | 492 DCHECK(!it.second->IsPartiallyCleared()); |
| 487 DCHECK(!it->second->Is3D()); | 493 DCHECK(!it.second->Is3D()); |
| 488 buffers[it->first - GL_COLOR_ATTACHMENT0] = it->first; | 494 buffers[it.first - GL_COLOR_ATTACHMENT0] = it.first; |
| 489 } | 495 } |
| 490 } | 496 } |
| 491 bool different = false; | 497 bool different = false; |
| 492 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) { | 498 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) { |
| 493 if (buffers[i] != draw_buffers_[i]) { | 499 if (buffers[i] != adjusted_draw_buffers_[i]) { |
| 494 different = true; | 500 different = true; |
| 495 break; | 501 break; |
| 496 } | 502 } |
| 497 } | 503 } |
| 498 if (different) | 504 if (different) |
| 499 glDrawBuffersARB(manager_->max_draw_buffers_, buffers.get()); | 505 glDrawBuffersARB(manager_->max_draw_buffers_, buffers.get()); |
| 500 return different; | 506 return different; |
| 501 } | 507 } |
| 502 | 508 |
| 503 void Framebuffer::RestoreDrawBuffersAfterClear() const { | 509 void Framebuffer::RestoreDrawBuffers() const { |
| 504 glDrawBuffersARB(manager_->max_draw_buffers_, draw_buffers_.get()); | 510 glDrawBuffersARB(manager_->max_draw_buffers_, adjusted_draw_buffers_.get()); |
| 511 } | |
| 512 | |
| 513 bool Framebuffer::ValidateAndAdjustDrawBuffers( | |
| 514 uint32_t fragment_output_type_mask, uint32_t fragment_output_written_mask) { | |
| 515 uint32_t mask = draw_buffer_bound_mask_ & fragment_output_written_mask; | |
| 516 if ((mask & fragment_output_type_mask) != (mask & draw_buffer_type_mask_)) | |
| 517 return false; | |
| 518 | |
| 519 if (draw_buffer_bound_mask_ & ~fragment_output_written_mask) { | |
| 520 // This won't be reached in every draw/clear call - only when framebuffer | |
| 521 // or program has changed. | |
| 522 for (uint32_t ii = 0; ii < manager_->max_draw_buffers_; ++ii) { | |
| 523 adjusted_draw_buffers_[ii] = draw_buffers_[ii]; | |
| 524 uint32_t shift_bits = ii * 2; | |
| 525 uint32_t mask = 0x33 << shift_bits; | |
|
piman
2016/07/14 23:41:14
Did you mean 0x3 instead of 0x33?
piman
2016/07/14 23:41:14
nit: this |mask| hides the variable on l.515 - it
Zhenyao Mo
2016/07/15 02:41:15
Done.
| |
| 526 if ((draw_buffer_bound_mask_ & mask) == 0u) { | |
| 527 adjusted_draw_buffers_[ii] = GL_NONE; | |
| 528 continue; | |
| 529 } | |
| 530 if ((fragment_output_written_mask & mask) == 0u) { | |
| 531 adjusted_draw_buffers_[ii] = GL_NONE; | |
| 532 } | |
| 533 } | |
| 534 glDrawBuffersARB(manager_->max_draw_buffers_, adjusted_draw_buffers_.get()); | |
| 535 } | |
| 536 return true; | |
| 537 } | |
| 538 | |
| 539 bool Framebuffer::ContainsActiveIntegerAttachments() const { | |
| 540 // SHADER_VARIABLE_FLOAT is 0x3. | |
|
piman
2016/07/14 23:41:14
nit: if you want to defend against this changing,
Zhenyao Mo
2016/07/15 02:41:15
Ha, nice trick. Thanks.
| |
| 541 uint32_t mask = 0xFFFFFFFF & draw_buffer_bound_mask_; | |
| 542 return draw_buffer_type_mask_ != mask; | |
| 505 } | 543 } |
| 506 | 544 |
| 507 void Framebuffer::ClearUnclearedIntOr3DTexturesOrPartiallyClearedTextures( | 545 void Framebuffer::ClearUnclearedIntOr3DTexturesOrPartiallyClearedTextures( |
| 508 GLES2Decoder* decoder, | 546 GLES2Decoder* decoder, TextureManager* texture_manager) { |
| 509 TextureManager* texture_manager) { | |
| 510 for (AttachmentMap::const_iterator it = attachments_.begin(); | 547 for (AttachmentMap::const_iterator it = attachments_.begin(); |
| 511 it != attachments_.end(); ++it) { | 548 it != attachments_.end(); ++it) { |
| 512 if (!it->second->IsTextureAttachment() || it->second->cleared()) | 549 if (!it->second->IsTextureAttachment() || it->second->cleared()) |
| 513 continue; | 550 continue; |
| 514 TextureAttachment* attachment = | 551 TextureAttachment* attachment = |
| 515 reinterpret_cast<TextureAttachment*>(it->second.get()); | 552 reinterpret_cast<TextureAttachment*>(it->second.get()); |
| 516 if (attachment->IsPartiallyCleared() || attachment->Is3D() || | 553 if (attachment->IsPartiallyCleared() || attachment->Is3D() || |
| 517 GLES2Util::IsIntegerFormat(attachment->internal_format())) { | 554 GLES2Util::IsIntegerFormat(attachment->internal_format())) { |
| 518 texture_manager->ClearTextureLevel(decoder, | 555 texture_manager->ClearTextureLevel(decoder, |
| 519 attachment->texture(), | 556 attachment->texture(), |
| 520 attachment->target(), | 557 attachment->target(), |
| 521 attachment->level()); | 558 attachment->level()); |
| 522 } | 559 } |
| 523 } | 560 } |
| 524 } | 561 } |
| 525 | 562 |
| 526 void Framebuffer::MarkAttachmentAsCleared( | 563 void Framebuffer::MarkAttachmentAsCleared( |
| 527 RenderbufferManager* renderbuffer_manager, | 564 RenderbufferManager* renderbuffer_manager, |
| 528 TextureManager* texture_manager, | 565 TextureManager* texture_manager, |
| 529 GLenum attachment, | 566 GLenum attachment, |
| 530 bool cleared) { | 567 bool cleared) { |
| 531 AttachmentMap::iterator it = attachments_.find(attachment); | 568 AttachmentMap::iterator it = attachments_.find(attachment); |
| 532 if (it != attachments_.end()) { | 569 if (it != attachments_.end()) { |
| 533 Attachment* a = it->second.get(); | 570 Attachment* a = it->second.get(); |
| 534 if (a->cleared() != cleared) { | 571 if (a->cleared() != cleared) { |
| 535 a->SetCleared(renderbuffer_manager, | 572 a->SetCleared(renderbuffer_manager, |
| 536 texture_manager, | 573 texture_manager, |
| 537 cleared); | 574 cleared); |
| 538 } | 575 } |
| 539 } | 576 } |
| 540 } | 577 } |
| 541 | 578 |
| 542 void Framebuffer::MarkAttachmentsAsCleared( | 579 void Framebuffer::MarkAttachmentsAsCleared( |
| 543 RenderbufferManager* renderbuffer_manager, | 580 RenderbufferManager* renderbuffer_manager, |
| 544 TextureManager* texture_manager, | 581 TextureManager* texture_manager, |
| 545 bool cleared) { | 582 bool cleared) { |
| 546 for (AttachmentMap::iterator it = attachments_.begin(); | 583 for (AttachmentMap::iterator it = attachments_.begin(); |
| 547 it != attachments_.end(); ++it) { | 584 it != attachments_.end(); ++it) { |
| 548 Attachment* attachment = it->second.get(); | 585 Attachment* attachment = it->second.get(); |
| 549 if (attachment->cleared() != cleared) { | 586 if (attachment->cleared() != cleared) { |
| 550 attachment->SetCleared(renderbuffer_manager, texture_manager, cleared); | 587 attachment->SetCleared(renderbuffer_manager, texture_manager, cleared); |
| 551 } | 588 } |
| 552 } | 589 } |
| 553 } | 590 } |
| 554 | 591 |
| 555 bool Framebuffer::HasColorAttachment(int index) const { | 592 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 { | 775 GLenum Framebuffer::GetDrawBuffer(GLenum draw_buffer) const { |
| 739 GLsizei index = static_cast<GLsizei>( | 776 GLsizei index = static_cast<GLsizei>( |
| 740 draw_buffer - GL_DRAW_BUFFER0_ARB); | 777 draw_buffer - GL_DRAW_BUFFER0_ARB); |
| 741 CHECK(index >= 0 && | 778 CHECK(index >= 0 && |
| 742 index < static_cast<GLsizei>(manager_->max_draw_buffers_)); | 779 index < static_cast<GLsizei>(manager_->max_draw_buffers_)); |
| 743 return draw_buffers_[index]; | 780 return draw_buffers_[index]; |
| 744 } | 781 } |
| 745 | 782 |
| 746 void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) { | 783 void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) { |
| 747 DCHECK(n <= static_cast<GLsizei>(manager_->max_draw_buffers_)); | 784 DCHECK(n <= static_cast<GLsizei>(manager_->max_draw_buffers_)); |
| 748 for (GLsizei i = 0; i < n; ++i) | 785 for (GLsizei ii = 0; ii < n; ++ii) { |
| 749 draw_buffers_[i] = bufs[i]; | 786 draw_buffers_[ii] = bufs[ii]; |
| 787 adjusted_draw_buffers_[ii] = bufs[ii]; | |
| 788 } | |
| 789 for (uint32_t ii = n; ii < manager_->max_draw_buffers_; ++ii) { | |
| 790 draw_buffers_[ii] = GL_NONE; | |
| 791 adjusted_draw_buffers_[ii] = GL_NONE; | |
| 792 } | |
| 793 UpdateDrawBufferMasks(); | |
| 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 (GLenum ii = GL_COLOR_ATTACHMENT0; | |
| 869 ii < GL_COLOR_ATTACHMENT0 + manager_->max_color_attachments_; ++ii) { | |
|
piman
2016/07/14 23:41:14
nit: how about: for (size_t index = 0; index < man
Zhenyao Mo
2016/07/15 02:41:15
Done.
| |
| 870 size_t index = ii - GL_COLOR_ATTACHMENT0; | |
| 871 if (draw_buffers_[index] == GL_NONE) | |
| 872 continue; | |
| 873 auto iter = attachments_.find(ii); | |
| 874 if (iter == attachments_.end()) | |
| 875 continue; | |
| 876 scoped_refptr<Attachment> attachment = iter->second; | |
| 877 GLenum internal_format = attachment->internal_format(); | |
| 878 ShaderVariableBaseType base_type = SHADER_VARIABLE_UNDEFINED_TYPE; | |
| 879 if (GLES2Util::IsSignedIntegerFormat(internal_format)) { | |
| 880 base_type = SHADER_VARIABLE_INT; | |
| 881 } else if (GLES2Util::IsUnsignedIntegerFormat(internal_format)) { | |
| 882 base_type = SHADER_VARIABLE_UINT; | |
| 883 } else { | |
| 884 base_type = SHADER_VARIABLE_FLOAT; | |
| 885 } | |
| 886 size_t shift_bits = index * 2; | |
| 887 draw_buffer_type_mask_ |= base_type << shift_bits; | |
| 888 draw_buffer_bound_mask_ |= 0x3 << shift_bits; | |
| 889 } | |
| 890 } | |
| 891 | |
| 821 Framebuffer* FramebufferManager::GetFramebuffer( | 892 Framebuffer* FramebufferManager::GetFramebuffer( |
| 822 GLuint client_id) { | 893 GLuint client_id) { |
| 823 FramebufferMap::iterator it = framebuffers_.find(client_id); | 894 FramebufferMap::iterator it = framebuffers_.find(client_id); |
| 824 return it != framebuffers_.end() ? it->second.get() : NULL; | 895 return it != framebuffers_.end() ? it->second.get() : NULL; |
| 825 } | 896 } |
| 826 | 897 |
| 827 void FramebufferManager::RemoveFramebuffer(GLuint client_id) { | 898 void FramebufferManager::RemoveFramebuffer(GLuint client_id) { |
| 828 FramebufferMap::iterator it = framebuffers_.find(client_id); | 899 FramebufferMap::iterator it = framebuffers_.find(client_id); |
| 829 if (it != framebuffers_.end()) { | 900 if (it != framebuffers_.end()) { |
| 830 it->second->MarkAsDeleted(); | 901 it->second->MarkAsDeleted(); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 934 | 1005 |
| 935 bool FramebufferManager::IsComplete( | 1006 bool FramebufferManager::IsComplete( |
| 936 Framebuffer* framebuffer) { | 1007 Framebuffer* framebuffer) { |
| 937 DCHECK(framebuffer); | 1008 DCHECK(framebuffer); |
| 938 return framebuffer->framebuffer_complete_state_count_id() == | 1009 return framebuffer->framebuffer_complete_state_count_id() == |
| 939 framebuffer_state_change_count_; | 1010 framebuffer_state_change_count_; |
| 940 } | 1011 } |
| 941 | 1012 |
| 942 } // namespace gles2 | 1013 } // namespace gles2 |
| 943 } // namespace gpu | 1014 } // namespace gpu |
| OLD | NEW |