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 7894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7905 } | 7905 } |
7906 | 7906 |
7907 GLsizei read_buffer_samples = GetBoundFramebufferSamples(GL_READ_FRAMEBUFFER); | 7907 GLsizei read_buffer_samples = GetBoundFramebufferSamples(GL_READ_FRAMEBUFFER); |
7908 if (read_buffer_samples > 0 && | 7908 if (read_buffer_samples > 0 && |
7909 (srcX0 != dstX0 || srcY0 != dstY0 || srcX1 != dstX1 || srcY1 != dstY1)) { | 7909 (srcX0 != dstX0 || srcY0 != dstY0 || srcX1 != dstX1 || srcY1 != dstY1)) { |
7910 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, | 7910 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
7911 "src framebuffer is multisampled, but src/dst regions are different"); | 7911 "src framebuffer is multisampled, but src/dst regions are different"); |
7912 return; | 7912 return; |
7913 } | 7913 } |
7914 | 7914 |
| 7915 // Detect that designated read/depth/stencil buffer in read framebuffer miss |
| 7916 // image, and the corresponding buffers in draw framebuffer have image. |
| 7917 bool read_framebuffer_miss_image = false; |
| 7918 |
7915 // Check whether read framebuffer and draw framebuffer have identical image | 7919 // Check whether read framebuffer and draw framebuffer have identical image |
7916 // TODO(yunchao): consider doing something like CheckFramebufferStatus(). | 7920 // TODO(yunchao): consider doing something like CheckFramebufferStatus(). |
7917 // We cache the validation results, and if read_framebuffer doesn't change, | 7921 // We cache the validation results, and if read_framebuffer doesn't change, |
7918 // draw_framebuffer doesn't change, then use the cached status. | 7922 // draw_framebuffer doesn't change, then use the cached status. |
7919 enum FeedbackLoopState { | 7923 enum FeedbackLoopState { |
7920 FeedbackLoopTrue, | 7924 FeedbackLoopTrue, |
7921 FeedbackLoopFalse, | 7925 FeedbackLoopFalse, |
7922 FeedbackLoopUnknown | 7926 FeedbackLoopUnknown |
7923 }; | 7927 }; |
7924 | 7928 |
7925 FeedbackLoopState is_feedback_loop = FeedbackLoopUnknown; | 7929 FeedbackLoopState is_feedback_loop = FeedbackLoopUnknown; |
7926 Framebuffer* read_framebuffer = | 7930 Framebuffer* read_framebuffer = |
7927 framebuffer_state_.bound_read_framebuffer.get(); | 7931 framebuffer_state_.bound_read_framebuffer.get(); |
7928 Framebuffer* draw_framebuffer = | 7932 Framebuffer* draw_framebuffer = |
7929 framebuffer_state_.bound_draw_framebuffer.get(); | 7933 framebuffer_state_.bound_draw_framebuffer.get(); |
7930 // If both read framebuffer and draw framebuffer are default framebuffer, | 7934 // If both read framebuffer and draw framebuffer are default framebuffer, |
7931 // They always have identical image. Otherwise, if one of read framebuffer | 7935 // They always have identical image. Otherwise, if one of read framebuffer |
7932 // and draw framebuffe is default framebuffer, but the other is fbo, they | 7936 // and draw framebuffe is default framebuffer, but the other is fbo, they |
7933 // always have no identical image. | 7937 // always have no identical image. |
7934 if (!read_framebuffer && !draw_framebuffer) { | 7938 if (!read_framebuffer && !draw_framebuffer) { |
7935 is_feedback_loop = FeedbackLoopTrue; | 7939 is_feedback_loop = FeedbackLoopTrue; |
7936 } else if (!read_framebuffer || !draw_framebuffer) { | 7940 } else if (!read_framebuffer || !draw_framebuffer) { |
7937 is_feedback_loop = FeedbackLoopFalse; | 7941 is_feedback_loop = FeedbackLoopFalse; |
| 7942 if (read_framebuffer) { |
| 7943 if (((mask & GL_COLOR_BUFFER_BIT) != 0 && |
| 7944 !GetBoundReadFramebufferInternalFormat()) || |
| 7945 ((mask & GL_DEPTH_BUFFER_BIT) != 0 && |
| 7946 !read_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT) && |
| 7947 BoundFramebufferHasDepthAttachment()) || |
| 7948 ((mask & GL_STENCIL_BUFFER_BIT) != 0 && |
| 7949 !read_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT) && |
| 7950 BoundFramebufferHasStencilAttachment())) { |
| 7951 read_framebuffer_miss_image = true; |
| 7952 } |
| 7953 } |
7938 } else { | 7954 } else { |
7939 DCHECK(read_framebuffer && draw_framebuffer); | 7955 DCHECK(read_framebuffer && draw_framebuffer); |
7940 if ((mask & GL_DEPTH_BUFFER_BIT) != 0) { | 7956 if ((mask & GL_DEPTH_BUFFER_BIT) != 0) { |
7941 const Framebuffer::Attachment* depth_buffer_read = | 7957 const Framebuffer::Attachment* depth_buffer_read = |
7942 read_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT); | 7958 read_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT); |
7943 const Framebuffer::Attachment* depth_buffer_draw = | 7959 const Framebuffer::Attachment* depth_buffer_draw = |
7944 draw_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT); | 7960 draw_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT); |
7945 if (!depth_buffer_draw || !depth_buffer_read) { | 7961 if (!depth_buffer_draw || !depth_buffer_read) { |
7946 mask &= ~GL_DEPTH_BUFFER_BIT; | 7962 mask &= ~GL_DEPTH_BUFFER_BIT; |
| 7963 if (depth_buffer_draw) { |
| 7964 read_framebuffer_miss_image = true; |
| 7965 } |
7947 } else if (depth_buffer_draw->IsSameAttachment(depth_buffer_read)) { | 7966 } else if (depth_buffer_draw->IsSameAttachment(depth_buffer_read)) { |
7948 is_feedback_loop = FeedbackLoopTrue; | 7967 is_feedback_loop = FeedbackLoopTrue; |
7949 } | 7968 } |
7950 } | 7969 } |
7951 if ((mask & GL_STENCIL_BUFFER_BIT) != 0) { | 7970 if ((mask & GL_STENCIL_BUFFER_BIT) != 0) { |
7952 const Framebuffer::Attachment* stencil_buffer_read = | 7971 const Framebuffer::Attachment* stencil_buffer_read = |
7953 read_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT); | 7972 read_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT); |
7954 const Framebuffer::Attachment* stencil_buffer_draw = | 7973 const Framebuffer::Attachment* stencil_buffer_draw = |
7955 draw_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT); | 7974 draw_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT); |
7956 if (!stencil_buffer_draw || !stencil_buffer_read) { | 7975 if (!stencil_buffer_draw || !stencil_buffer_read) { |
7957 mask &= ~GL_STENCIL_BUFFER_BIT; | 7976 mask &= ~GL_STENCIL_BUFFER_BIT; |
| 7977 if (stencil_buffer_draw) { |
| 7978 read_framebuffer_miss_image = true; |
| 7979 } |
7958 } else if (stencil_buffer_draw->IsSameAttachment(stencil_buffer_read)) { | 7980 } else if (stencil_buffer_draw->IsSameAttachment(stencil_buffer_read)) { |
7959 is_feedback_loop = FeedbackLoopTrue; | 7981 is_feedback_loop = FeedbackLoopTrue; |
7960 } | 7982 } |
7961 } | 7983 } |
7962 if (!mask) | 7984 if (!mask && !read_framebuffer_miss_image) |
7963 return; | 7985 return; |
7964 } | 7986 } |
7965 | 7987 |
7966 GLenum src_internal_format = GetBoundReadFramebufferInternalFormat(); | 7988 GLenum src_internal_format = GetBoundReadFramebufferInternalFormat(); |
7967 GLenum src_type = GetBoundReadFramebufferTextureType(); | 7989 GLenum src_type = GetBoundReadFramebufferTextureType(); |
7968 | 7990 |
7969 bool read_buffer_has_srgb = | 7991 bool read_buffer_has_srgb = |
7970 GetColorEncodingFromInternalFormat(src_internal_format) == GL_SRGB; | 7992 GetColorEncodingFromInternalFormat(src_internal_format) == GL_SRGB; |
7971 bool draw_buffers_has_srgb = false; | 7993 bool draw_buffers_has_srgb = false; |
7972 if ((mask & GL_COLOR_BUFFER_BIT) != 0) { | 7994 if ((mask & GL_COLOR_BUFFER_BIT) != 0) { |
(...skipping 14 matching lines...) Expand all Loading... |
7987 DCHECK(read_framebuffer || (is_feedback_loop != FeedbackLoopUnknown)); | 8009 DCHECK(read_framebuffer || (is_feedback_loop != FeedbackLoopUnknown)); |
7988 const Framebuffer::Attachment* read_buffer = | 8010 const Framebuffer::Attachment* read_buffer = |
7989 is_feedback_loop == FeedbackLoopUnknown ? | 8011 is_feedback_loop == FeedbackLoopUnknown ? |
7990 read_framebuffer->GetReadBufferAttachment() : nullptr; | 8012 read_framebuffer->GetReadBufferAttachment() : nullptr; |
7991 for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) { | 8013 for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) { |
7992 GLenum dst_format = GetBoundColorDrawBufferInternalFormat( | 8014 GLenum dst_format = GetBoundColorDrawBufferInternalFormat( |
7993 static_cast<GLint>(ii)); | 8015 static_cast<GLint>(ii)); |
7994 GLenum dst_type = GetBoundColorDrawBufferType(static_cast<GLint>(ii)); | 8016 GLenum dst_type = GetBoundColorDrawBufferType(static_cast<GLint>(ii)); |
7995 if (dst_format == 0) | 8017 if (dst_format == 0) |
7996 continue; | 8018 continue; |
| 8019 if (!src_internal_format) { |
| 8020 read_framebuffer_miss_image = true; |
| 8021 } |
7997 if (GetColorEncodingFromInternalFormat(dst_format) == GL_SRGB) | 8022 if (GetColorEncodingFromInternalFormat(dst_format) == GL_SRGB) |
7998 draw_buffers_has_srgb = true; | 8023 draw_buffers_has_srgb = true; |
7999 if (read_buffer_samples > 0 && | 8024 if (read_buffer_samples > 0 && |
8000 (src_sized_format != | 8025 (src_sized_format != |
8001 GLES2Util::ConvertToSizedFormat(dst_format, dst_type))) { | 8026 GLES2Util::ConvertToSizedFormat(dst_format, dst_type))) { |
8002 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, | 8027 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
8003 "src and dst formats differ for color"); | 8028 "src and dst formats differ for color"); |
8004 return; | 8029 return; |
8005 } | 8030 } |
8006 bool is_dst_signed_int = GLES2Util::IsSignedIntegerFormat(dst_format); | 8031 bool is_dst_signed_int = GLES2Util::IsSignedIntegerFormat(dst_format); |
(...skipping 19 matching lines...) Expand all Loading... |
8026 break; | 8051 break; |
8027 } | 8052 } |
8028 } | 8053 } |
8029 } | 8054 } |
8030 } | 8055 } |
8031 if (is_feedback_loop == FeedbackLoopTrue) { | 8056 if (is_feedback_loop == FeedbackLoopTrue) { |
8032 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, | 8057 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
8033 "source buffer and destination buffers are identical"); | 8058 "source buffer and destination buffers are identical"); |
8034 return; | 8059 return; |
8035 } | 8060 } |
| 8061 if (read_framebuffer_miss_image == true) { |
| 8062 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 8063 "The designated attachment point(s) in read framebuffer miss image"); |
| 8064 return; |
| 8065 } |
8036 | 8066 |
8037 if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) { | 8067 if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) { |
8038 if (filter != GL_NEAREST) { | 8068 if (filter != GL_NEAREST) { |
8039 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, | 8069 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
8040 "invalid filter for depth/stencil"); | 8070 "invalid filter for depth/stencil"); |
8041 return; | 8071 return; |
8042 } | 8072 } |
8043 | 8073 |
8044 if ((GetBoundFramebufferDepthFormat(GL_READ_FRAMEBUFFER) != | 8074 if ((GetBoundFramebufferDepthFormat(GL_READ_FRAMEBUFFER) != |
8045 GetBoundFramebufferDepthFormat(GL_DRAW_FRAMEBUFFER)) || | 8075 GetBoundFramebufferDepthFormat(GL_DRAW_FRAMEBUFFER)) || |
(...skipping 10927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18973 } | 19003 } |
18974 | 19004 |
18975 // Include the auto-generated part of this file. We split this because it means | 19005 // Include the auto-generated part of this file. We split this because it means |
18976 // we can easily edit the non-auto generated parts right here in this file | 19006 // we can easily edit the non-auto generated parts right here in this file |
18977 // instead of having to edit some template or the code generator. | 19007 // instead of having to edit some template or the code generator. |
18978 #include "base/macros.h" | 19008 #include "base/macros.h" |
18979 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 19009 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
18980 | 19010 |
18981 } // namespace gles2 | 19011 } // namespace gles2 |
18982 } // namespace gpu | 19012 } // namespace gpu |
OLD | NEW |