| 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/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 6 | 6 |
| 7 #include <limits.h> | 7 #include <limits.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 #include <stdio.h> | 10 #include <stdio.h> |
| (...skipping 7529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7540 } | 7540 } |
| 7541 | 7541 |
| 7542 GLsizei read_buffer_samples = GetBoundFramebufferSamples(GL_READ_FRAMEBUFFER); | 7542 GLsizei read_buffer_samples = GetBoundFramebufferSamples(GL_READ_FRAMEBUFFER); |
| 7543 if (read_buffer_samples > 0 && | 7543 if (read_buffer_samples > 0 && |
| 7544 (srcX0 != dstX0 || srcY0 != dstY0 || srcX1 != dstX1 || srcY1 != dstY1)) { | 7544 (srcX0 != dstX0 || srcY0 != dstY0 || srcX1 != dstX1 || srcY1 != dstY1)) { |
| 7545 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, | 7545 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 7546 "src framebuffer is multisampled, but src/dst regions are different"); | 7546 "src framebuffer is multisampled, but src/dst regions are different"); |
| 7547 return; | 7547 return; |
| 7548 } | 7548 } |
| 7549 | 7549 |
| 7550 // Check whether read framebuffer and draw framebuffer have identical image |
| 7551 // TODO(yunchao): consider doing something like CheckFramebufferStatus(). |
| 7552 // We cache the validation results, and if read_framebuffer doesn't change, |
| 7553 // draw_framebuffer doesn't change, then use the cached status. |
| 7554 enum FeedbackLoopState { |
| 7555 FeedbackLoopTrue, |
| 7556 FeedbackLoopFalse, |
| 7557 FeedbackLoopUnknown |
| 7558 }; |
| 7559 |
| 7560 FeedbackLoopState is_feedback_loop = FeedbackLoopUnknown; |
| 7561 Framebuffer* read_framebuffer = |
| 7562 framebuffer_state_.bound_read_framebuffer.get(); |
| 7563 Framebuffer* draw_framebuffer = |
| 7564 framebuffer_state_.bound_draw_framebuffer.get(); |
| 7565 // If both read framebuffer and draw framebuffer are default framebuffer, |
| 7566 // They always have identical image. Otherwise, if one of read framebuffer |
| 7567 // and draw framebuffe is default framebuffer, but the other is fbo, they |
| 7568 // always have no identical image. |
| 7569 if (!read_framebuffer && !draw_framebuffer) { |
| 7570 is_feedback_loop = FeedbackLoopTrue; |
| 7571 } else if (!read_framebuffer || !draw_framebuffer) { |
| 7572 is_feedback_loop = FeedbackLoopFalse; |
| 7573 } |
| 7574 if ((mask & GL_DEPTH_BUFFER_BIT) != 0) { |
| 7575 const Framebuffer::Attachment* depth_buffer_read = |
| 7576 read_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT); |
| 7577 const Framebuffer::Attachment* depth_buffer_draw = |
| 7578 draw_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT); |
| 7579 if (depth_buffer_draw && |
| 7580 depth_buffer_draw->IsSameAttachment(depth_buffer_read)) { |
| 7581 is_feedback_loop = FeedbackLoopTrue; |
| 7582 } |
| 7583 } |
| 7584 if ((mask & GL_STENCIL_BUFFER_BIT) != 0) { |
| 7585 const Framebuffer::Attachment* stencil_buffer_read = |
| 7586 read_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT); |
| 7587 const Framebuffer::Attachment* stencil_buffer_draw = |
| 7588 draw_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT); |
| 7589 if (stencil_buffer_draw && |
| 7590 stencil_buffer_draw->IsSameAttachment(stencil_buffer_read)) { |
| 7591 is_feedback_loop = FeedbackLoopTrue; |
| 7592 } |
| 7593 } |
| 7594 |
| 7550 GLenum src_format = GetBoundReadFramebufferInternalFormat(); | 7595 GLenum src_format = GetBoundReadFramebufferInternalFormat(); |
| 7551 GLenum src_type = GetBoundReadFramebufferTextureType(); | 7596 GLenum src_type = GetBoundReadFramebufferTextureType(); |
| 7552 | 7597 |
| 7553 if ((mask & GL_COLOR_BUFFER_BIT) != 0) { | 7598 if ((mask & GL_COLOR_BUFFER_BIT) != 0) { |
| 7554 bool is_src_signed_int = GLES2Util::IsSignedIntegerFormat(src_format); | 7599 bool is_src_signed_int = GLES2Util::IsSignedIntegerFormat(src_format); |
| 7555 bool is_src_unsigned_int = GLES2Util::IsUnsignedIntegerFormat(src_format); | 7600 bool is_src_unsigned_int = GLES2Util::IsUnsignedIntegerFormat(src_format); |
| 7556 DCHECK(!is_src_signed_int || !is_src_unsigned_int); | 7601 DCHECK(!is_src_signed_int || !is_src_unsigned_int); |
| 7557 | 7602 |
| 7558 if ((is_src_signed_int || is_src_unsigned_int) && filter == GL_LINEAR) { | 7603 if ((is_src_signed_int || is_src_unsigned_int) && filter == GL_LINEAR) { |
| 7559 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, | 7604 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 7560 "invalid filter for integer format"); | 7605 "invalid filter for integer format"); |
| 7561 return; | 7606 return; |
| 7562 } | 7607 } |
| 7563 | 7608 |
| 7564 GLenum src_sized_format = | 7609 GLenum src_sized_format = |
| 7565 GLES2Util::ConvertToSizedFormat(src_format, src_type); | 7610 GLES2Util::ConvertToSizedFormat(src_format, src_type); |
| 7611 const Framebuffer::Attachment* read_buffer = |
| 7612 is_feedback_loop == FeedbackLoopUnknown ? |
| 7613 read_framebuffer->GetReadBufferAttachment() : nullptr; |
| 7566 for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) { | 7614 for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) { |
| 7567 GLenum dst_format = GetBoundColorDrawBufferInternalFormat( | 7615 GLenum dst_format = GetBoundColorDrawBufferInternalFormat( |
| 7568 static_cast<GLint>(ii)); | 7616 static_cast<GLint>(ii)); |
| 7569 GLenum dst_type = GetBoundColorDrawBufferType(static_cast<GLint>(ii)); | 7617 GLenum dst_type = GetBoundColorDrawBufferType(static_cast<GLint>(ii)); |
| 7570 if (dst_format == 0) | 7618 if (dst_format == 0) |
| 7571 continue; | 7619 continue; |
| 7572 if (read_buffer_samples > 0 && | 7620 if (read_buffer_samples > 0 && |
| 7573 (src_sized_format != | 7621 (src_sized_format != |
| 7574 GLES2Util::ConvertToSizedFormat(dst_format, dst_type))) { | 7622 GLES2Util::ConvertToSizedFormat(dst_format, dst_type))) { |
| 7575 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, | 7623 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 7576 "src and dst formats differ for color"); | 7624 "src and dst formats differ for color"); |
| 7577 return; | 7625 return; |
| 7578 } | 7626 } |
| 7579 bool is_dst_signed_int = GLES2Util::IsSignedIntegerFormat(dst_format); | 7627 bool is_dst_signed_int = GLES2Util::IsSignedIntegerFormat(dst_format); |
| 7580 bool is_dst_unsigned_int = GLES2Util::IsUnsignedIntegerFormat(dst_format); | 7628 bool is_dst_unsigned_int = GLES2Util::IsUnsignedIntegerFormat(dst_format); |
| 7581 DCHECK(!is_dst_signed_int || !is_dst_unsigned_int); | 7629 DCHECK(!is_dst_signed_int || !is_dst_unsigned_int); |
| 7582 if (is_src_signed_int != is_dst_signed_int || | 7630 if (is_src_signed_int != is_dst_signed_int || |
| 7583 is_src_unsigned_int != is_dst_unsigned_int) { | 7631 is_src_unsigned_int != is_dst_unsigned_int) { |
| 7584 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, | 7632 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 7585 "incompatible src/dst color formats"); | 7633 "incompatible src/dst color formats"); |
| 7586 return; | 7634 return; |
| 7587 } | 7635 } |
| 7636 // Check whether draw buffers have identical color image with read buffer |
| 7637 if (is_feedback_loop == FeedbackLoopUnknown) { |
| 7638 GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + ii); |
| 7639 const Framebuffer::Attachment* draw_buffer = |
| 7640 draw_framebuffer->GetAttachment(attachment); |
| 7641 if (!draw_buffer) { |
| 7642 continue; |
| 7643 } |
| 7644 if (draw_buffer->IsSameAttachment(read_buffer)) { |
| 7645 is_feedback_loop = FeedbackLoopTrue; |
| 7646 break; |
| 7647 } |
| 7648 } |
| 7588 } | 7649 } |
| 7589 } | 7650 } |
| 7651 if (is_feedback_loop == FeedbackLoopTrue) { |
| 7652 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 7653 "source buffer and destination buffers are identical"); |
| 7654 return; |
| 7655 } |
| 7590 | 7656 |
| 7591 if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) { | 7657 if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) { |
| 7592 if (filter != GL_NEAREST) { | 7658 if (filter != GL_NEAREST) { |
| 7593 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, | 7659 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 7594 "invalid filter for depth/stencil"); | 7660 "invalid filter for depth/stencil"); |
| 7595 return; | 7661 return; |
| 7596 } | 7662 } |
| 7597 | 7663 |
| 7598 if ((GetBoundFramebufferDepthFormat(GL_READ_FRAMEBUFFER) != | 7664 if ((GetBoundFramebufferDepthFormat(GL_READ_FRAMEBUFFER) != |
| 7599 GetBoundFramebufferDepthFormat(GL_DRAW_FRAMEBUFFER)) || | 7665 GetBoundFramebufferDepthFormat(GL_DRAW_FRAMEBUFFER)) || |
| (...skipping 10307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17907 } | 17973 } |
| 17908 | 17974 |
| 17909 // Include the auto-generated part of this file. We split this because it means | 17975 // Include the auto-generated part of this file. We split this because it means |
| 17910 // we can easily edit the non-auto generated parts right here in this file | 17976 // we can easily edit the non-auto generated parts right here in this file |
| 17911 // instead of having to edit some template or the code generator. | 17977 // instead of having to edit some template or the code generator. |
| 17912 #include "base/macros.h" | 17978 #include "base/macros.h" |
| 17913 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 17979 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 17914 | 17980 |
| 17915 } // namespace gles2 | 17981 } // namespace gles2 |
| 17916 } // namespace gpu | 17982 } // namespace gpu |
| OLD | NEW |