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