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" |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
| 13 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 13 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 14 #include "gpu/command_buffer/service/framebuffer_completeness_cache.h" | 14 #include "gpu/command_buffer/service/framebuffer_completeness_cache.h" |
| 15 #include "gpu/command_buffer/service/renderbuffer_manager.h" | 15 #include "gpu/command_buffer/service/renderbuffer_manager.h" |
| 16 #include "gpu/command_buffer/service/texture_manager.h" | 16 #include "gpu/command_buffer/service/texture_manager.h" |
| 17 #include "ui/gl/gl_bindings.h" | 17 #include "ui/gl/gl_bindings.h" |
| 18 | 18 |
| 19 namespace gpu { | 19 namespace gpu { |
| 20 namespace gles2 { | 20 namespace gles2 { |
| 21 | 21 |
| 22 namespace { | |
| 23 | |
| 24 bool DetectWebGL1DepthStencilAttachmentConflicts( | |
| 25 uint32_t needed_channels, uint32_t channels) { | |
| 26 switch (needed_channels) { | |
| 27 case GLES2Util::kDepth: | |
| 28 case GLES2Util::kStencil: | |
| 29 case GLES2Util::kDepth | GLES2Util::kStencil: | |
| 30 return (needed_channels != channels); | |
| 31 default: | |
| 32 return false; | |
| 33 } | |
| 34 } | |
| 35 | |
| 36 } // namespace anonymous | |
| 37 | |
| 38 DecoderFramebufferState::DecoderFramebufferState() | 22 DecoderFramebufferState::DecoderFramebufferState() |
| 39 : clear_state_dirty(false), | 23 : clear_state_dirty(false), |
| 40 bound_read_framebuffer(NULL), | 24 bound_read_framebuffer(NULL), |
| 41 bound_draw_framebuffer(NULL) { | 25 bound_draw_framebuffer(NULL) { |
| 42 } | 26 } |
| 43 | 27 |
| 44 DecoderFramebufferState::~DecoderFramebufferState() { | 28 DecoderFramebufferState::~DecoderFramebufferState() { |
| 45 } | 29 } |
| 46 | 30 |
| 47 class RenderbufferAttachment | 31 class RenderbufferAttachment |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 102 | 86 |
| 103 bool CanRenderTo(const FeatureInfo*) const override { return true; } | 87 bool CanRenderTo(const FeatureInfo*) const override { return true; } |
| 104 | 88 |
| 105 void DetachFromFramebuffer(Framebuffer* framebuffer) const override { | 89 void DetachFromFramebuffer(Framebuffer* framebuffer) const override { |
| 106 // Nothing to do for renderbuffers. | 90 // Nothing to do for renderbuffers. |
| 107 } | 91 } |
| 108 | 92 |
| 109 bool IsLayerValid() const override { return true; } | 93 bool IsLayerValid() const override { return true; } |
| 110 | 94 |
| 111 bool ValidForAttachmentType(GLenum attachment_type, | 95 bool ValidForAttachmentType(GLenum attachment_type, |
| 112 ContextType context_type, | |
| 113 uint32_t max_color_attachments) override { | 96 uint32_t max_color_attachments) override { |
| 114 uint32_t need = GLES2Util::GetChannelsNeededForAttachmentType( | 97 uint32_t need = GLES2Util::GetChannelsNeededForAttachmentType( |
| 115 attachment_type, max_color_attachments); | 98 attachment_type, max_color_attachments); |
| 116 DCHECK_NE(0u, need); | 99 DCHECK_NE(0u, need); |
| 117 uint32_t have = GLES2Util::GetChannelsForFormat(internal_format()); | 100 uint32_t have = GLES2Util::GetChannelsForFormat(internal_format()); |
| 118 if (context_type == CONTEXT_TYPE_WEBGL1 && | |
| 119 DetectWebGL1DepthStencilAttachmentConflicts(need, have)) | |
| 120 return false; | |
| 121 return (need & have) != 0; | 101 return (need & have) != 0; |
| 122 } | 102 } |
| 123 | 103 |
| 124 Renderbuffer* renderbuffer() const { | 104 Renderbuffer* renderbuffer() const { |
| 125 return renderbuffer_.get(); | 105 return renderbuffer_.get(); |
| 126 } | 106 } |
| 127 | 107 |
| 128 size_t GetSignatureSize(TextureManager* texture_manager) const override { | 108 size_t GetSignatureSize(TextureManager* texture_manager) const override { |
| 129 return renderbuffer_->GetSignatureSize(); | 109 return renderbuffer_->GetSignatureSize(); |
| 130 } | 110 } |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 264 | 244 |
| 265 bool IsLayerValid() const override { | 245 bool IsLayerValid() const override { |
| 266 Texture* texture = texture_ref_->texture(); | 246 Texture* texture = texture_ref_->texture(); |
| 267 DCHECK(texture); | 247 DCHECK(texture); |
| 268 GLsizei width, height, depth; | 248 GLsizei width, height, depth; |
| 269 return (texture->GetLevelSize(target_, level_, &width, &height, &depth) && | 249 return (texture->GetLevelSize(target_, level_, &width, &height, &depth) && |
| 270 layer_ < depth); | 250 layer_ < depth); |
| 271 } | 251 } |
| 272 | 252 |
| 273 bool ValidForAttachmentType(GLenum attachment_type, | 253 bool ValidForAttachmentType(GLenum attachment_type, |
| 274 ContextType context_type, | |
| 275 uint32_t max_color_attachments) override { | 254 uint32_t max_color_attachments) override { |
| 276 GLenum type = 0; | 255 GLenum type = 0; |
| 277 GLenum internal_format = 0; | 256 GLenum internal_format = 0; |
| 278 if (!texture_ref_->texture()->GetLevelType( | 257 if (!texture_ref_->texture()->GetLevelType( |
| 279 target_, level_, &type, &internal_format)) { | 258 target_, level_, &type, &internal_format)) { |
| 280 return false; | 259 return false; |
| 281 } | 260 } |
| 282 uint32_t need = GLES2Util::GetChannelsNeededForAttachmentType( | 261 uint32_t need = GLES2Util::GetChannelsNeededForAttachmentType( |
| 283 attachment_type, max_color_attachments); | 262 attachment_type, max_color_attachments); |
| 284 DCHECK_NE(0u, need); | 263 DCHECK_NE(0u, need); |
| 285 uint32_t have = GLES2Util::GetChannelsForFormat(internal_format); | 264 uint32_t have = GLES2Util::GetChannelsForFormat(internal_format); |
| 286 | 265 |
| 287 // Workaround for NVIDIA drivers that incorrectly expose these formats as | 266 // Workaround for NVIDIA drivers that incorrectly expose these formats as |
| 288 // renderable: | 267 // renderable: |
| 289 if (internal_format == GL_LUMINANCE || internal_format == GL_ALPHA || | 268 if (internal_format == GL_LUMINANCE || internal_format == GL_ALPHA || |
| 290 internal_format == GL_LUMINANCE_ALPHA) { | 269 internal_format == GL_LUMINANCE_ALPHA) { |
| 291 return false; | 270 return false; |
| 292 } | 271 } |
| 293 if (context_type == CONTEXT_TYPE_WEBGL1 && | |
| 294 DetectWebGL1DepthStencilAttachmentConflicts(need, have)) | |
| 295 return need == have; | |
| 296 return (need & have) != 0; | 272 return (need & have) != 0; |
| 297 } | 273 } |
| 298 | 274 |
| 299 size_t GetSignatureSize(TextureManager* texture_manager) const override { | 275 size_t GetSignatureSize(TextureManager* texture_manager) const override { |
| 300 return texture_manager->GetSignatureSize(); | 276 return texture_manager->GetSignatureSize(); |
| 301 } | 277 } |
| 302 | 278 |
| 303 void AddToSignature(TextureManager* texture_manager, | 279 void AddToSignature(TextureManager* texture_manager, |
| 304 std::string* signature) const override { | 280 std::string* signature) const override { |
| 305 DCHECK(signature); | 281 DCHECK(signature); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 326 GLint level_; | 302 GLint level_; |
| 327 GLsizei samples_; | 303 GLsizei samples_; |
| 328 GLint layer_; | 304 GLint layer_; |
| 329 | 305 |
| 330 DISALLOW_COPY_AND_ASSIGN(TextureAttachment); | 306 DISALLOW_COPY_AND_ASSIGN(TextureAttachment); |
| 331 }; | 307 }; |
| 332 | 308 |
| 333 FramebufferManager::FramebufferManager( | 309 FramebufferManager::FramebufferManager( |
| 334 uint32_t max_draw_buffers, | 310 uint32_t max_draw_buffers, |
| 335 uint32_t max_color_attachments, | 311 uint32_t max_color_attachments, |
| 336 ContextType context_type, | |
| 337 const scoped_refptr<FramebufferCompletenessCache>& | 312 const scoped_refptr<FramebufferCompletenessCache>& |
| 338 framebuffer_combo_complete_cache) | 313 framebuffer_combo_complete_cache) |
| 339 : framebuffer_state_change_count_(1), | 314 : framebuffer_state_change_count_(1), |
| 340 framebuffer_count_(0), | 315 framebuffer_count_(0), |
| 341 have_context_(true), | 316 have_context_(true), |
| 342 max_draw_buffers_(max_draw_buffers), | 317 max_draw_buffers_(max_draw_buffers), |
| 343 max_color_attachments_(max_color_attachments), | 318 max_color_attachments_(max_color_attachments), |
| 344 context_type_(context_type), | |
| 345 framebuffer_combo_complete_cache_(framebuffer_combo_complete_cache) { | 319 framebuffer_combo_complete_cache_(framebuffer_combo_complete_cache) { |
| 346 DCHECK_GT(max_draw_buffers_, 0u); | 320 DCHECK_GT(max_draw_buffers_, 0u); |
| 347 DCHECK_GT(max_color_attachments_, 0u); | 321 DCHECK_GT(max_color_attachments_, 0u); |
| 348 } | 322 } |
| 349 | 323 |
| 350 FramebufferManager::~FramebufferManager() { | 324 FramebufferManager::~FramebufferManager() { |
| 351 DCHECK(framebuffers_.empty()); | 325 DCHECK(framebuffers_.empty()); |
| 352 // If this triggers, that means something is keeping a reference to a | 326 // If this triggers, that means something is keeping a reference to a |
| 353 // Framebuffer belonging to this. | 327 // Framebuffer belonging to this. |
| 354 CHECK_EQ(framebuffer_count_, 0u); | 328 CHECK_EQ(framebuffer_count_, 0u); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 glDeleteFramebuffersEXT(1, &id); | 393 glDeleteFramebuffersEXT(1, &id); |
| 420 } | 394 } |
| 421 manager_->StopTracking(this); | 395 manager_->StopTracking(this); |
| 422 manager_ = NULL; | 396 manager_ = NULL; |
| 423 } | 397 } |
| 424 } | 398 } |
| 425 | 399 |
| 426 bool Framebuffer::HasUnclearedAttachment( | 400 bool Framebuffer::HasUnclearedAttachment( |
| 427 GLenum attachment_type) const { | 401 GLenum attachment_type) const { |
| 428 const Attachment* attachment = GetAttachment(attachment_type); | 402 const Attachment* attachment = GetAttachment(attachment_type); |
| 429 switch (attachment_type) { | |
| 430 case GL_DEPTH_ATTACHMENT: | |
| 431 case GL_STENCIL_ATTACHMENT: | |
| 432 attachment = attachment ? attachment : | |
| 433 GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT); | |
| 434 break; | |
| 435 default: | |
| 436 break; | |
| 437 } | |
| 438 return attachment && !attachment->cleared(); | 403 return attachment && !attachment->cleared(); |
| 439 } | 404 } |
| 440 | 405 |
| 441 bool Framebuffer::HasDepthStencilFormatAttachment() const { | 406 bool Framebuffer::HasDepthStencilFormatAttachment() const { |
| 442 const Attachment* depth_attachment = GetAttachment(GL_DEPTH_ATTACHMENT); | 407 const Attachment* depth_attachment = GetAttachment(GL_DEPTH_ATTACHMENT); |
| 443 const Attachment* stencil_attachment = GetAttachment(GL_STENCIL_ATTACHMENT); | 408 const Attachment* stencil_attachment = GetAttachment(GL_STENCIL_ATTACHMENT); |
| 444 const Attachment* depth_stencil_attachment = GetAttachment( | |
| 445 GL_DEPTH_STENCIL_ATTACHMENT); | |
| 446 if (depth_attachment && stencil_attachment) { | 409 if (depth_attachment && stencil_attachment) { |
| 447 GLenum depth_format = depth_attachment->internal_format(); | 410 GLenum depth_format = depth_attachment->internal_format(); |
| 448 depth_format = TextureManager::ExtractFormatFromStorageFormat(depth_format); | 411 depth_format = TextureManager::ExtractFormatFromStorageFormat(depth_format); |
| 449 GLenum stencil_format = stencil_attachment->internal_format(); | 412 GLenum stencil_format = stencil_attachment->internal_format(); |
| 450 stencil_format = TextureManager::ExtractFormatFromStorageFormat( | 413 stencil_format = TextureManager::ExtractFormatFromStorageFormat( |
| 451 stencil_format); | 414 stencil_format); |
| 452 return depth_format == GL_DEPTH_STENCIL && | 415 return depth_format == GL_DEPTH_STENCIL && |
| 453 stencil_format == GL_DEPTH_STENCIL; | 416 stencil_format == GL_DEPTH_STENCIL; |
| 454 } | |
| 455 if (depth_stencil_attachment) { | |
| 456 GLenum depth_stencil_format = depth_stencil_attachment->internal_format(); | |
| 457 depth_stencil_format = TextureManager::ExtractFormatFromStorageFormat( | |
| 458 depth_stencil_format); | |
| 459 return depth_stencil_format == GL_DEPTH_STENCIL; | |
| 460 } | 417 } |
| 461 return false; | 418 return false; |
| 462 } | 419 } |
| 463 | 420 |
| 464 bool Framebuffer::HasUnclearedColorAttachments() const { | 421 bool Framebuffer::HasUnclearedColorAttachments() const { |
| 465 for (AttachmentMap::const_iterator it = attachments_.begin(); | 422 for (AttachmentMap::const_iterator it = attachments_.begin(); |
| 466 it != attachments_.end(); ++it) { | 423 it != attachments_.end(); ++it) { |
| 467 if (it->first >= GL_COLOR_ATTACHMENT0 && | 424 if (it->first >= GL_COLOR_ATTACHMENT0 && |
| 468 it->first < GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_) { | 425 it->first < GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_) { |
| 469 const Attachment* attachment = it->second.get(); | 426 const Attachment* attachment = it->second.get(); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 640 attachment->SetCleared(renderbuffer_manager, texture_manager, cleared); | 597 attachment->SetCleared(renderbuffer_manager, texture_manager, cleared); |
| 641 } | 598 } |
| 642 } | 599 } |
| 643 } | 600 } |
| 644 | 601 |
| 645 bool Framebuffer::HasColorAttachment(int index) const { | 602 bool Framebuffer::HasColorAttachment(int index) const { |
| 646 return attachments_.find(GL_COLOR_ATTACHMENT0 + index) != attachments_.end(); | 603 return attachments_.find(GL_COLOR_ATTACHMENT0 + index) != attachments_.end(); |
| 647 } | 604 } |
| 648 | 605 |
| 649 bool Framebuffer::HasDepthAttachment() const { | 606 bool Framebuffer::HasDepthAttachment() const { |
| 650 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || | 607 return attachments_.find(GL_DEPTH_ATTACHMENT) != attachments_.end(); |
| 651 attachments_.find(GL_DEPTH_ATTACHMENT) != attachments_.end(); | |
| 652 } | 608 } |
| 653 | 609 |
| 654 bool Framebuffer::HasStencilAttachment() const { | 610 bool Framebuffer::HasStencilAttachment() const { |
| 655 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || | 611 return attachments_.find(GL_STENCIL_ATTACHMENT) != attachments_.end(); |
| 656 attachments_.find(GL_STENCIL_ATTACHMENT) != attachments_.end(); | |
| 657 } | 612 } |
| 658 | 613 |
| 659 GLenum Framebuffer::GetReadBufferInternalFormat() const { | 614 GLenum Framebuffer::GetReadBufferInternalFormat() const { |
| 660 if (read_buffer_ == GL_NONE) | 615 if (read_buffer_ == GL_NONE) |
| 661 return 0; | 616 return 0; |
| 662 AttachmentMap::const_iterator it = attachments_.find(read_buffer_); | 617 AttachmentMap::const_iterator it = attachments_.find(read_buffer_); |
| 663 if (it == attachments_.end()) { | 618 if (it == attachments_.end()) { |
| 664 return 0; | 619 return 0; |
| 665 } | 620 } |
| 666 const Attachment* attachment = it->second.get(); | 621 const Attachment* attachment = it->second.get(); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 685 GLsizei Framebuffer::GetSamples() const { | 640 GLsizei Framebuffer::GetSamples() const { |
| 686 // Assume the framebuffer is complete, so return any attachment's samples. | 641 // Assume the framebuffer is complete, so return any attachment's samples. |
| 687 auto iter = attachments_.begin(); | 642 auto iter = attachments_.begin(); |
| 688 if (iter == attachments_.end()) | 643 if (iter == attachments_.end()) |
| 689 return -1; | 644 return -1; |
| 690 Attachment* attachment = iter->second.get(); | 645 Attachment* attachment = iter->second.get(); |
| 691 DCHECK(attachment); | 646 DCHECK(attachment); |
| 692 return attachment->samples(); | 647 return attachment->samples(); |
| 693 } | 648 } |
| 694 | 649 |
| 695 const Framebuffer::Attachment* Framebuffer::GetDepthAttachment() const { | 650 GLenum Framebuffer::GetDepthFormat() const { |
| 696 auto iter = attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT); | 651 auto iter = attachments_.find(GL_DEPTH_ATTACHMENT); |
| 697 if (iter == attachments_.end()) | 652 if (iter == attachments_.end()) |
| 698 iter = attachments_.find(GL_DEPTH_ATTACHMENT); | 653 return 0; |
| 699 if (iter == attachments_.end()) | |
| 700 return nullptr; | |
| 701 Attachment* attachment = iter->second.get(); | 654 Attachment* attachment = iter->second.get(); |
| 702 DCHECK(attachment); | 655 DCHECK(attachment); |
| 703 return attachment; | 656 return attachment->internal_format(); |
| 704 } | |
| 705 | |
| 706 const Framebuffer::Attachment* Framebuffer::GetStencilAttachment() const { | |
| 707 auto iter = attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT); | |
| 708 if (iter == attachments_.end()) | |
| 709 iter = attachments_.find(GL_STENCIL_ATTACHMENT); | |
| 710 if (iter == attachments_.end()) | |
| 711 return nullptr; | |
| 712 Attachment* attachment = iter->second.get(); | |
| 713 DCHECK(attachment); | |
| 714 return attachment; | |
| 715 } | |
| 716 | |
| 717 GLenum Framebuffer::GetDepthFormat() const { | |
| 718 const Attachment* attachment = GetDepthAttachment(); | |
| 719 return attachment ? attachment->internal_format() : 0; | |
| 720 } | 657 } |
| 721 | 658 |
| 722 GLenum Framebuffer::GetStencilFormat() const { | 659 GLenum Framebuffer::GetStencilFormat() const { |
| 723 const Attachment* attachment = GetStencilAttachment(); | 660 auto iter = attachments_.find(GL_STENCIL_ATTACHMENT); |
| 724 return attachment ? attachment->internal_format() : 0; | 661 if (iter == attachments_.end()) |
| 662 return 0; | |
| 663 Attachment* attachment = iter->second.get(); | |
| 664 DCHECK(attachment); | |
| 665 return attachment->internal_format(); | |
| 725 } | 666 } |
| 726 | 667 |
| 727 GLenum Framebuffer::IsPossiblyComplete(const FeatureInfo* feature_info) const { | 668 GLenum Framebuffer::IsPossiblyComplete(const FeatureInfo* feature_info) const { |
| 728 if (attachments_.empty()) { | 669 if (attachments_.empty()) { |
| 729 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; | 670 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; |
| 730 } | 671 } |
| 731 | 672 |
| 732 GLsizei width = -1; | 673 GLsizei width = -1; |
| 733 GLsizei height = -1; | 674 GLsizei height = -1; |
| 734 GLsizei samples = -1; | 675 GLsizei samples = -1; |
| 735 const bool kSamplesMustMatch = feature_info->IsWebGLContext() || | 676 const bool kSamplesMustMatch = feature_info->IsWebGLContext() || |
| 736 !feature_info->feature_flags().chromium_framebuffer_mixed_samples; | 677 !feature_info->feature_flags().chromium_framebuffer_mixed_samples; |
| 737 | 678 |
| 738 for (AttachmentMap::const_iterator it = attachments_.begin(); | 679 for (AttachmentMap::const_iterator it = attachments_.begin(); |
| 739 it != attachments_.end(); ++it) { | 680 it != attachments_.end(); ++it) { |
| 740 GLenum attachment_type = it->first; | 681 GLenum attachment_type = it->first; |
| 741 Attachment* attachment = it->second.get(); | 682 Attachment* attachment = it->second.get(); |
| 742 if (!attachment->ValidForAttachmentType(attachment_type, | 683 if (!attachment->ValidForAttachmentType(attachment_type, |
| 743 feature_info->context_type(), | |
| 744 manager_->max_color_attachments_)) { | 684 manager_->max_color_attachments_)) { |
| 745 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; | 685 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
| 746 } | 686 } |
| 747 if (!attachment->IsLayerValid()) { | 687 if (!attachment->IsLayerValid()) { |
| 748 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; | 688 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
| 749 } | 689 } |
| 750 if (width < 0) { | 690 if (width < 0) { |
| 751 width = attachment->width(); | 691 width = attachment->width(); |
| 752 height = attachment->height(); | 692 height = attachment->height(); |
| 753 if (width == 0 || height == 0) { | 693 if (width == 0 || height == 0) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 789 } | 729 } |
| 790 | 730 |
| 791 // Binding different images to depth and stencil attachment points should | 731 // Binding different images to depth and stencil attachment points should |
| 792 // return FRAMEBUFFER_UNSUPPORTED. | 732 // return FRAMEBUFFER_UNSUPPORTED. |
| 793 const Attachment* depth_attachment = GetAttachment(GL_DEPTH_ATTACHMENT); | 733 const Attachment* depth_attachment = GetAttachment(GL_DEPTH_ATTACHMENT); |
| 794 const Attachment* stencil_attachment = GetAttachment(GL_STENCIL_ATTACHMENT); | 734 const Attachment* stencil_attachment = GetAttachment(GL_STENCIL_ATTACHMENT); |
| 795 if (depth_attachment && stencil_attachment) { | 735 if (depth_attachment && stencil_attachment) { |
| 796 if (!depth_attachment->IsSameAttachment(stencil_attachment)) { | 736 if (!depth_attachment->IsSameAttachment(stencil_attachment)) { |
| 797 return GL_FRAMEBUFFER_UNSUPPORTED; | 737 return GL_FRAMEBUFFER_UNSUPPORTED; |
| 798 } | 738 } |
| 739 DCHECK_EQ(depth_attachment->internal_format(), | |
| 740 stencil_attachment->internal_format()); | |
| 741 } | |
| 742 if (feature_info->context_type() == CONTEXT_TYPE_WEBGL1) { | |
| 743 // WebGL1 has specific additional restrictions on depth and stencil | |
| 744 // attachments (e.g. it is forbidden to bind a DEPTH_STENCIL attachement to | |
| 745 // a (pure) GL_DEPTH_ATTACHMENT. Note that in WebGL1, | |
| 746 // GL_DEPTH_STENCIL_ATTACHMENT is a separate bind point, but that logic is | |
| 747 // handled in Blink and translated to | |
| 748 // GL_DEPTH_ATTACHMENT+GL_STENCIL_ATTACHMENT. | |
| 749 uint32_t need_channels = 0; | |
| 750 uint32_t have_channels = 0; | |
| 751 if (depth_attachment) { | |
| 752 need_channels |= GLES2Util::kDepth; | |
| 753 have_channels |= | |
| 754 GLES2Util::GetChannelsForFormat(depth_attachment->internal_format()); | |
| 755 } | |
| 756 if (stencil_attachment) { | |
| 757 need_channels |= GLES2Util::kStencil; | |
| 758 have_channels |= GLES2Util::GetChannelsForFormat( | |
| 759 stencil_attachment->internal_format()); | |
| 760 } | |
| 761 if (need_channels != have_channels) | |
| 762 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; | |
|
Ken Russell (switch to Gerrit)
2016/09/29 03:07:43
It's awesome that the command buffer's knowledge o
| |
| 799 } | 763 } |
| 800 | 764 |
| 801 // This does not mean the framebuffer is actually complete. It just means our | 765 // This does not mean the framebuffer is actually complete. It just means our |
| 802 // checks passed. | 766 // checks passed. |
| 803 return GL_FRAMEBUFFER_COMPLETE; | 767 return GL_FRAMEBUFFER_COMPLETE; |
| 804 } | 768 } |
| 805 | 769 |
| 806 GLenum Framebuffer::GetStatus( | 770 GLenum Framebuffer::GetStatus( |
| 807 TextureManager* texture_manager, GLenum target) const { | 771 TextureManager* texture_manager, GLenum target) const { |
| 808 if (!manager_->GetFramebufferComboCompleteCache()) { | 772 if (!manager_->GetFramebufferComboCompleteCache()) { |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 990 void Framebuffer::DoUnbindGLAttachmentsForWorkaround(GLenum target) { | 954 void Framebuffer::DoUnbindGLAttachmentsForWorkaround(GLenum target) { |
| 991 // Replace all attachments with the default Renderbuffer. | 955 // Replace all attachments with the default Renderbuffer. |
| 992 for (AttachmentMap::const_iterator it = attachments_.begin(); | 956 for (AttachmentMap::const_iterator it = attachments_.begin(); |
| 993 it != attachments_.end(); ++it) { | 957 it != attachments_.end(); ++it) { |
| 994 glFramebufferRenderbufferEXT(target, it->first, GL_RENDERBUFFER, 0); | 958 glFramebufferRenderbufferEXT(target, it->first, GL_RENDERBUFFER, 0); |
| 995 } | 959 } |
| 996 } | 960 } |
| 997 | 961 |
| 998 void Framebuffer::AttachRenderbuffer( | 962 void Framebuffer::AttachRenderbuffer( |
| 999 GLenum attachment, Renderbuffer* renderbuffer) { | 963 GLenum attachment, Renderbuffer* renderbuffer) { |
| 964 DCHECK(attachment != GL_DEPTH_STENCIL_ATTACHMENT); | |
| 1000 const Attachment* a = GetAttachment(attachment); | 965 const Attachment* a = GetAttachment(attachment); |
| 1001 if (a) | 966 if (a) |
| 1002 a->DetachFromFramebuffer(this); | 967 a->DetachFromFramebuffer(this); |
| 1003 if (renderbuffer) { | 968 if (renderbuffer) { |
| 1004 attachments_[attachment] = scoped_refptr<Attachment>( | 969 attachments_[attachment] = scoped_refptr<Attachment>( |
| 1005 new RenderbufferAttachment(renderbuffer)); | 970 new RenderbufferAttachment(renderbuffer)); |
| 1006 } else { | 971 } else { |
| 1007 attachments_.erase(attachment); | 972 attachments_.erase(attachment); |
| 1008 } | 973 } |
| 1009 framebuffer_complete_state_count_id_ = 0; | 974 framebuffer_complete_state_count_id_ = 0; |
| 1010 } | 975 } |
| 1011 | 976 |
| 1012 void Framebuffer::AttachTexture( | 977 void Framebuffer::AttachTexture( |
| 1013 GLenum attachment, TextureRef* texture_ref, GLenum target, | 978 GLenum attachment, TextureRef* texture_ref, GLenum target, |
| 1014 GLint level, GLsizei samples) { | 979 GLint level, GLsizei samples) { |
| 980 DCHECK(attachment != GL_DEPTH_STENCIL_ATTACHMENT); | |
| 1015 const Attachment* a = GetAttachment(attachment); | 981 const Attachment* a = GetAttachment(attachment); |
| 1016 if (a) | 982 if (a) |
| 1017 a->DetachFromFramebuffer(this); | 983 a->DetachFromFramebuffer(this); |
| 1018 if (texture_ref) { | 984 if (texture_ref) { |
| 1019 attachments_[attachment] = scoped_refptr<Attachment>( | 985 attachments_[attachment] = scoped_refptr<Attachment>( |
| 1020 new TextureAttachment(texture_ref, target, level, samples, 0)); | 986 new TextureAttachment(texture_ref, target, level, samples, 0)); |
| 1021 texture_ref->texture()->AttachToFramebuffer(); | 987 texture_ref->texture()->AttachToFramebuffer(); |
| 1022 } else { | 988 } else { |
| 1023 attachments_.erase(attachment); | 989 attachments_.erase(attachment); |
| 1024 } | 990 } |
| 1025 framebuffer_complete_state_count_id_ = 0; | 991 framebuffer_complete_state_count_id_ = 0; |
| 1026 } | 992 } |
| 1027 | 993 |
| 1028 void Framebuffer::AttachTextureLayer( | 994 void Framebuffer::AttachTextureLayer( |
| 1029 GLenum attachment, TextureRef* texture_ref, GLenum target, | 995 GLenum attachment, TextureRef* texture_ref, GLenum target, |
| 1030 GLint level, GLint layer) { | 996 GLint level, GLint layer) { |
| 997 DCHECK(attachment != GL_DEPTH_STENCIL_ATTACHMENT); | |
| 1031 const Attachment* a = GetAttachment(attachment); | 998 const Attachment* a = GetAttachment(attachment); |
| 1032 if (a) | 999 if (a) |
| 1033 a->DetachFromFramebuffer(this); | 1000 a->DetachFromFramebuffer(this); |
| 1034 if (texture_ref) { | 1001 if (texture_ref) { |
| 1035 attachments_[attachment] = scoped_refptr<Attachment>( | 1002 attachments_[attachment] = scoped_refptr<Attachment>( |
| 1036 new TextureAttachment(texture_ref, target, level, 0, layer)); | 1003 new TextureAttachment(texture_ref, target, level, 0, layer)); |
| 1037 texture_ref->texture()->AttachToFramebuffer(); | 1004 texture_ref->texture()->AttachToFramebuffer(); |
| 1038 } else { | 1005 } else { |
| 1039 attachments_.erase(attachment); | 1006 attachments_.erase(attachment); |
| 1040 } | 1007 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1089 | 1056 |
| 1090 bool FramebufferManager::IsComplete( | 1057 bool FramebufferManager::IsComplete( |
| 1091 Framebuffer* framebuffer) { | 1058 Framebuffer* framebuffer) { |
| 1092 DCHECK(framebuffer); | 1059 DCHECK(framebuffer); |
| 1093 return framebuffer->framebuffer_complete_state_count_id() == | 1060 return framebuffer->framebuffer_complete_state_count_id() == |
| 1094 framebuffer_state_change_count_; | 1061 framebuffer_state_change_count_; |
| 1095 } | 1062 } |
| 1096 | 1063 |
| 1097 } // namespace gles2 | 1064 } // namespace gles2 |
| 1098 } // namespace gpu | 1065 } // namespace gpu |
| OLD | NEW |