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

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

Issue 2142353002: Validate fbo color image format and fragment shader output variable type. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix Created 4 years, 5 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
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/framebuffer_manager.h ('k') | gpu/command_buffer/service/framebuffer_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698