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 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 read_buffer_(GL_COLOR_ATTACHMENT0) { | 375 read_buffer_(GL_COLOR_ATTACHMENT0) { |
376 manager->StartTracking(this); | 376 manager->StartTracking(this); |
377 DCHECK_GT(manager->max_draw_buffers_, 0u); | 377 DCHECK_GT(manager->max_draw_buffers_, 0u); |
378 draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]); | 378 draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]); |
379 adjusted_draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]); | |
379 draw_buffers_[0] = GL_COLOR_ATTACHMENT0; | 380 draw_buffers_[0] = GL_COLOR_ATTACHMENT0; |
380 for (uint32_t i = 1; i < manager->max_draw_buffers_; ++i) | 381 adjusted_draw_buffers_[0] = GL_COLOR_ATTACHMENT0; |
381 draw_buffers_[i] = GL_NONE; | 382 for (uint32_t ii = 1; ii < manager->max_draw_buffers_; ++ii) { |
383 draw_buffers_[ii] = GL_NONE; | |
384 adjusted_draw_buffers_[ii] = GL_NONE; | |
385 } | |
386 | |
387 color_attachment_base_types_.reset( | |
388 new ShaderVariableBaseType[manager->max_draw_buffers_]); | |
389 ResetColorAttachmentBaseTypes(); | |
382 } | 390 } |
383 | 391 |
384 Framebuffer::~Framebuffer() { | 392 Framebuffer::~Framebuffer() { |
385 if (manager_) { | 393 if (manager_) { |
386 if (manager_->have_context_) { | 394 if (manager_->have_context_) { |
387 GLuint id = service_id(); | 395 GLuint id = service_id(); |
388 glDeleteFramebuffersEXT(1, &id); | 396 glDeleteFramebuffersEXT(1, &id); |
389 } | 397 } |
390 manager_->StopTracking(this); | 398 manager_->StopTracking(this); |
391 manager_ = NULL; | 399 manager_ = NULL; |
392 } | 400 } |
393 } | 401 } |
394 | 402 |
403 void Framebuffer::ResetColorAttachmentBaseTypes() { | |
404 for (size_t ii = 1; ii < manager_->max_draw_buffers_; ++ii) { | |
405 color_attachment_base_types_[ii] = SHADER_VARIABLE_UNDEFINED_TYPE; | |
406 } | |
407 } | |
408 | |
395 bool Framebuffer::HasUnclearedAttachment( | 409 bool Framebuffer::HasUnclearedAttachment( |
396 GLenum attachment) const { | 410 GLenum attachment) const { |
397 AttachmentMap::const_iterator it = | 411 AttachmentMap::const_iterator it = |
398 attachments_.find(attachment); | 412 attachments_.find(attachment); |
399 if (it != attachments_.end()) { | 413 if (it != attachments_.end()) { |
400 const Attachment* attachment = it->second.get(); | 414 const Attachment* attachment = it->second.get(); |
401 return !attachment->cleared(); | 415 return !attachment->cleared(); |
402 } | 416 } |
403 return false; | 417 return false; |
404 } | 418 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
463 case GL_SRGB_EXT: | 477 case GL_SRGB_EXT: |
464 case GL_SRGB_ALPHA_EXT: | 478 case GL_SRGB_ALPHA_EXT: |
465 return true; | 479 return true; |
466 default: | 480 default: |
467 break; | 481 break; |
468 } | 482 } |
469 } | 483 } |
470 return false; | 484 return false; |
471 } | 485 } |
472 | 486 |
473 bool Framebuffer::PrepareDrawBuffersForClear() const { | 487 bool Framebuffer::PrepareDrawBuffersForClearingUninitializedAttachments( |
488 ) const { | |
474 std::unique_ptr<GLenum[]> buffers(new GLenum[manager_->max_draw_buffers_]); | 489 std::unique_ptr<GLenum[]> buffers(new GLenum[manager_->max_draw_buffers_]); |
475 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) | 490 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) |
476 buffers[i] = GL_NONE; | 491 buffers[i] = GL_NONE; |
477 for (AttachmentMap::const_iterator it = attachments_.begin(); | 492 for (AttachmentMap::const_iterator it = attachments_.begin(); |
478 it != attachments_.end(); ++it) { | 493 it != attachments_.end(); ++it) { |
479 if (it->first >= GL_COLOR_ATTACHMENT0 && | 494 if (it->first >= GL_COLOR_ATTACHMENT0 && |
480 it->first < GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_ && | 495 it->first < GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_ && |
481 !it->second->cleared()) { | 496 !it->second->cleared()) { |
482 // There should be no partially cleared images, uncleared int/3d images. | 497 // There should be no partially cleared images, uncleared int/3d images. |
483 // This is because ClearUnclearedIntOr3DImagesOrPartiallyClearedImages() | 498 // This is because ClearUnclearedIntOr3DImagesOrPartiallyClearedImages() |
484 // is called before this. | 499 // is called before this. |
485 DCHECK(!GLES2Util::IsIntegerFormat(it->second->internal_format())); | 500 DCHECK(!GLES2Util::IsIntegerFormat(it->second->internal_format())); |
486 DCHECK(!it->second->IsPartiallyCleared()); | 501 DCHECK(!it->second->IsPartiallyCleared()); |
487 DCHECK(!it->second->Is3D()); | 502 DCHECK(!it->second->Is3D()); |
488 buffers[it->first - GL_COLOR_ATTACHMENT0] = it->first; | 503 buffers[it->first - GL_COLOR_ATTACHMENT0] = it->first; |
489 } | 504 } |
490 } | 505 } |
491 bool different = false; | 506 bool different = false; |
492 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) { | 507 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) { |
493 if (buffers[i] != draw_buffers_[i]) { | 508 if (buffers[i] != adjusted_draw_buffers_[i]) { |
494 different = true; | 509 different = true; |
495 break; | 510 break; |
496 } | 511 } |
497 } | 512 } |
498 if (different) | 513 if (different) |
499 glDrawBuffersARB(manager_->max_draw_buffers_, buffers.get()); | 514 glDrawBuffersARB(manager_->max_draw_buffers_, buffers.get()); |
500 return different; | 515 return different; |
501 } | 516 } |
502 | 517 |
503 void Framebuffer::RestoreDrawBuffersAfterClear() const { | 518 void Framebuffer::RestoreDrawBuffers() const { |
504 glDrawBuffersARB(manager_->max_draw_buffers_, draw_buffers_.get()); | 519 glDrawBuffersARB(manager_->max_draw_buffers_, adjusted_draw_buffers_.get()); |
520 } | |
521 | |
522 bool Framebuffer::ValidateAndAdjustDrawBuffers( | |
523 const ShaderVariableBaseType* fragment_output_base_types) { | |
524 bool adjust = false; | |
525 for (size_t ii = 0; ii < manager_->max_draw_buffers_; ++ii) { | |
piman
2016/07/13 22:35:55
This loop seems kind of expensive...
Truth is, we
| |
526 if (draw_buffers_[ii] == GL_NONE) { | |
527 DCHECK_EQ(static_cast<GLenum>(GL_NONE), adjusted_draw_buffers_[ii]); | |
528 continue; | |
529 } | |
530 if (color_attachment_base_types_[ii] == SHADER_VARIABLE_UNDEFINED_TYPE) { | |
531 if (adjusted_draw_buffers_[ii] != GL_NONE) | |
532 adjust = true; | |
533 continue; | |
534 } | |
535 if (fragment_output_base_types) { // Draw call cases. | |
536 if (fragment_output_base_types[ii] == SHADER_VARIABLE_UNDEFINED_TYPE) { | |
537 if (adjusted_draw_buffers_[ii] != GL_NONE) | |
538 adjust = true; | |
539 continue; | |
540 } | |
541 if (fragment_output_base_types[ii] != color_attachment_base_types_[ii]) { | |
542 return false; | |
543 } | |
544 } else { // Clear call cases. | |
545 if (color_attachment_base_types_[ii] != SHADER_VARIABLE_FLOAT) { | |
546 if (adjusted_draw_buffers_[ii] != GL_NONE) | |
547 adjust = true; | |
548 continue; | |
549 } | |
550 } | |
551 } | |
552 if (adjust) { | |
553 // This won't be reached in every draw/clear call - only when framebuffer | |
554 // or program has changed. | |
555 for (size_t ii = 0; ii < manager_->max_draw_buffers_; ++ii) { | |
556 if (draw_buffers_[ii] == GL_NONE) | |
557 continue; | |
558 if (color_attachment_base_types_[ii] == SHADER_VARIABLE_UNDEFINED_TYPE) { | |
559 adjusted_draw_buffers_[ii] = GL_NONE; | |
560 continue; | |
561 } | |
562 if (fragment_output_base_types) { // Draw call cases. | |
563 if (fragment_output_base_types[ii] == SHADER_VARIABLE_UNDEFINED_TYPE) { | |
564 adjusted_draw_buffers_[ii] = GL_NONE; | |
565 } | |
566 } else { // Clear call cases. | |
567 if (color_attachment_base_types_[ii] != SHADER_VARIABLE_FLOAT) { | |
568 adjusted_draw_buffers_[ii] = GL_NONE; | |
569 } | |
570 } | |
571 } | |
572 glDrawBuffersARB(manager_->max_draw_buffers_, adjusted_draw_buffers_.get()); | |
573 } | |
574 return true; | |
505 } | 575 } |
506 | 576 |
507 void Framebuffer::ClearUnclearedIntOr3DTexturesOrPartiallyClearedTextures( | 577 void Framebuffer::ClearUnclearedIntOr3DTexturesOrPartiallyClearedTextures( |
508 GLES2Decoder* decoder, | 578 GLES2Decoder* decoder, TextureManager* texture_manager) { |
509 TextureManager* texture_manager) { | |
510 for (AttachmentMap::const_iterator it = attachments_.begin(); | 579 for (AttachmentMap::const_iterator it = attachments_.begin(); |
511 it != attachments_.end(); ++it) { | 580 it != attachments_.end(); ++it) { |
512 if (!it->second->IsTextureAttachment() || it->second->cleared()) | 581 if (!it->second->IsTextureAttachment() || it->second->cleared()) |
513 continue; | 582 continue; |
514 TextureAttachment* attachment = | 583 TextureAttachment* attachment = |
515 reinterpret_cast<TextureAttachment*>(it->second.get()); | 584 reinterpret_cast<TextureAttachment*>(it->second.get()); |
516 if (attachment->IsPartiallyCleared() || attachment->Is3D() || | 585 if (attachment->IsPartiallyCleared() || attachment->Is3D() || |
517 GLES2Util::IsIntegerFormat(attachment->internal_format())) { | 586 GLES2Util::IsIntegerFormat(attachment->internal_format())) { |
518 texture_manager->ClearTextureLevel(decoder, | 587 texture_manager->ClearTextureLevel(decoder, |
519 attachment->texture(), | 588 attachment->texture(), |
520 attachment->target(), | 589 attachment->target(), |
521 attachment->level()); | 590 attachment->level()); |
522 } | 591 } |
523 } | 592 } |
524 } | 593 } |
525 | 594 |
526 void Framebuffer::MarkAttachmentAsCleared( | 595 void Framebuffer::MarkAttachmentAsCleared( |
527 RenderbufferManager* renderbuffer_manager, | 596 RenderbufferManager* renderbuffer_manager, |
528 TextureManager* texture_manager, | 597 TextureManager* texture_manager, |
529 GLenum attachment, | 598 GLenum attachment, |
530 bool cleared) { | 599 bool cleared) { |
531 AttachmentMap::iterator it = attachments_.find(attachment); | 600 AttachmentMap::iterator it = attachments_.find(attachment); |
532 if (it != attachments_.end()) { | 601 if (it != attachments_.end()) { |
533 Attachment* a = it->second.get(); | 602 Attachment* a = it->second.get(); |
534 if (a->cleared() != cleared) { | 603 if (a->cleared() != cleared) { |
535 a->SetCleared(renderbuffer_manager, | 604 a->SetCleared(renderbuffer_manager, |
536 texture_manager, | 605 texture_manager, |
537 cleared); | 606 cleared); |
538 } | 607 } |
539 } | 608 } |
540 } | 609 } |
541 | 610 |
542 void Framebuffer::MarkAttachmentsAsCleared( | 611 void Framebuffer::MarkAttachmentsAsCleared( |
543 RenderbufferManager* renderbuffer_manager, | 612 RenderbufferManager* renderbuffer_manager, |
544 TextureManager* texture_manager, | 613 TextureManager* texture_manager, |
545 bool cleared) { | 614 bool cleared) { |
546 for (AttachmentMap::iterator it = attachments_.begin(); | 615 for (AttachmentMap::iterator it = attachments_.begin(); |
547 it != attachments_.end(); ++it) { | 616 it != attachments_.end(); ++it) { |
548 Attachment* attachment = it->second.get(); | 617 Attachment* attachment = it->second.get(); |
549 if (attachment->cleared() != cleared) { | 618 if (attachment->cleared() != cleared) { |
550 attachment->SetCleared(renderbuffer_manager, texture_manager, cleared); | 619 attachment->SetCleared(renderbuffer_manager, texture_manager, cleared); |
551 } | 620 } |
552 } | 621 } |
553 } | 622 } |
554 | 623 |
555 bool Framebuffer::HasColorAttachment(int index) const { | 624 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 { | 807 GLenum Framebuffer::GetDrawBuffer(GLenum draw_buffer) const { |
739 GLsizei index = static_cast<GLsizei>( | 808 GLsizei index = static_cast<GLsizei>( |
740 draw_buffer - GL_DRAW_BUFFER0_ARB); | 809 draw_buffer - GL_DRAW_BUFFER0_ARB); |
741 CHECK(index >= 0 && | 810 CHECK(index >= 0 && |
742 index < static_cast<GLsizei>(manager_->max_draw_buffers_)); | 811 index < static_cast<GLsizei>(manager_->max_draw_buffers_)); |
743 return draw_buffers_[index]; | 812 return draw_buffers_[index]; |
744 } | 813 } |
745 | 814 |
746 void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) { | 815 void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) { |
747 DCHECK(n <= static_cast<GLsizei>(manager_->max_draw_buffers_)); | 816 DCHECK(n <= static_cast<GLsizei>(manager_->max_draw_buffers_)); |
748 for (GLsizei i = 0; i < n; ++i) | 817 for (GLsizei i = 0; i < n; ++i) { |
749 draw_buffers_[i] = bufs[i]; | 818 draw_buffers_[i] = bufs[i]; |
819 adjusted_draw_buffers_[i] = bufs[i]; | |
820 } | |
750 } | 821 } |
751 | 822 |
752 bool Framebuffer::HasAlphaMRT() const { | 823 bool Framebuffer::HasAlphaMRT() const { |
753 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) { | 824 for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) { |
754 if (draw_buffers_[i] != GL_NONE) { | 825 if (draw_buffers_[i] != GL_NONE) { |
755 const Attachment* attachment = GetAttachment(draw_buffers_[i]); | 826 const Attachment* attachment = GetAttachment(draw_buffers_[i]); |
756 if (!attachment) | 827 if (!attachment) |
757 continue; | 828 continue; |
758 if ((GLES2Util::GetChannelsForFormat( | 829 if ((GLES2Util::GetChannelsForFormat( |
759 attachment->internal_format()) & 0x0008) != 0) | 830 attachment->internal_format()) & 0x0008) != 0) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
811 // TODO(gman): manually detach texture. | 882 // TODO(gman): manually detach texture. |
812 // glFramebufferTexture2DEXT(target, it->first, GL_TEXTURE_2D, 0, 0); | 883 // glFramebufferTexture2DEXT(target, it->first, GL_TEXTURE_2D, 0, 0); |
813 AttachTexture(it->first, NULL, GL_TEXTURE_2D, 0, 0); | 884 AttachTexture(it->first, NULL, GL_TEXTURE_2D, 0, 0); |
814 done = false; | 885 done = false; |
815 break; | 886 break; |
816 } | 887 } |
817 } | 888 } |
818 } while (!done); | 889 } while (!done); |
819 } | 890 } |
820 | 891 |
892 void Framebuffer::UpdateColorAttachmentBaseTypes() { | |
893 ResetColorAttachmentBaseTypes(); | |
894 for (AttachmentMap::const_iterator it = attachments_.begin(); | |
895 it != attachments_.end(); ++it) { | |
896 if (it->first < GL_COLOR_ATTACHMENT0 || | |
897 it->first >= GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_) { | |
piman
2016/07/13 22:35:55
this should be manager_->max_color_attachments_
| |
898 continue; | |
899 } | |
900 size_t index = it->first - GL_COLOR_ATTACHMENT0; | |
piman
2016/07/13 22:35:55
I think there's confusion about how color_attachme
piman
2016/07/13 23:16:36
Ok, so I now understand, this works in ES because
| |
901 Attachment* attachment = it->second.get(); | |
902 GLenum internal_format = attachment->internal_format(); | |
903 if (GLES2Util::IsSignedIntegerFormat(internal_format)) { | |
904 color_attachment_base_types_[index] = SHADER_VARIABLE_INT; | |
905 } else if (GLES2Util::IsUnsignedIntegerFormat(internal_format)) { | |
906 color_attachment_base_types_[index] = SHADER_VARIABLE_UINT; | |
907 } else { | |
908 color_attachment_base_types_[index] = SHADER_VARIABLE_FLOAT; | |
909 } | |
910 } | |
911 } | |
912 | |
821 Framebuffer* FramebufferManager::GetFramebuffer( | 913 Framebuffer* FramebufferManager::GetFramebuffer( |
822 GLuint client_id) { | 914 GLuint client_id) { |
823 FramebufferMap::iterator it = framebuffers_.find(client_id); | 915 FramebufferMap::iterator it = framebuffers_.find(client_id); |
824 return it != framebuffers_.end() ? it->second.get() : NULL; | 916 return it != framebuffers_.end() ? it->second.get() : NULL; |
825 } | 917 } |
826 | 918 |
827 void FramebufferManager::RemoveFramebuffer(GLuint client_id) { | 919 void FramebufferManager::RemoveFramebuffer(GLuint client_id) { |
828 FramebufferMap::iterator it = framebuffers_.find(client_id); | 920 FramebufferMap::iterator it = framebuffers_.find(client_id); |
829 if (it != framebuffers_.end()) { | 921 if (it != framebuffers_.end()) { |
830 it->second->MarkAsDeleted(); | 922 it->second->MarkAsDeleted(); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
934 | 1026 |
935 bool FramebufferManager::IsComplete( | 1027 bool FramebufferManager::IsComplete( |
936 Framebuffer* framebuffer) { | 1028 Framebuffer* framebuffer) { |
937 DCHECK(framebuffer); | 1029 DCHECK(framebuffer); |
938 return framebuffer->framebuffer_complete_state_count_id() == | 1030 return framebuffer->framebuffer_complete_state_count_id() == |
939 framebuffer_state_change_count_; | 1031 framebuffer_state_change_count_; |
940 } | 1032 } |
941 | 1033 |
942 } // namespace gles2 | 1034 } // namespace gles2 |
943 } // namespace gpu | 1035 } // namespace gpu |
OLD | NEW |