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; |
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 |