| 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 <stdio.h> | 7 #include <stdio.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <list> | 10 #include <list> |
| (...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1317 // the tracing system. | 1317 // the tracing system. |
| 1318 void UpdateBackbufferMemoryAccounting(); | 1318 void UpdateBackbufferMemoryAccounting(); |
| 1319 | 1319 |
| 1320 // Returns true if the context was just lost due to e.g. GL_ARB_robustness. | 1320 // Returns true if the context was just lost due to e.g. GL_ARB_robustness. |
| 1321 bool WasContextLost(); | 1321 bool WasContextLost(); |
| 1322 | 1322 |
| 1323 #if defined(OS_MACOSX) | 1323 #if defined(OS_MACOSX) |
| 1324 void ReleaseIOSurfaceForTexture(GLuint texture_id); | 1324 void ReleaseIOSurfaceForTexture(GLuint texture_id); |
| 1325 #endif | 1325 #endif |
| 1326 | 1326 |
| 1327 // Validates the combination of texture parameters. For example validates that |
| 1328 // for a given format the specific type, level and targets are valid. |
| 1329 // Synthesizes the correct GL error if invalid. Returns true if valid. |
| 1330 bool ValidateTextureParameters( |
| 1331 const char* function_name, |
| 1332 GLenum target, GLenum format, GLenum type, GLint level); |
| 1333 |
| 1327 void LogMessage(const std::string& msg); | 1334 void LogMessage(const std::string& msg); |
| 1328 void RenderWarning(const std::string& msg); | 1335 void RenderWarning(const std::string& msg); |
| 1329 void PerformanceWarning(const std::string& msg); | 1336 void PerformanceWarning(const std::string& msg); |
| 1330 | 1337 |
| 1331 // Generate a member function prototype for each command in an automated and | 1338 // Generate a member function prototype for each command in an automated and |
| 1332 // typesafe way. | 1339 // typesafe way. |
| 1333 #define GLES2_CMD_OP(name) \ | 1340 #define GLES2_CMD_OP(name) \ |
| 1334 Error Handle ## name( \ | 1341 Error Handle ## name( \ |
| 1335 uint32 immediate_data_size, \ | 1342 uint32 immediate_data_size, \ |
| 1336 const gles2::name& args); \ | 1343 const gles2::name& args); \ |
| (...skipping 5323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6660 bool GLES2DecoderImpl::ClearLevel( | 6667 bool GLES2DecoderImpl::ClearLevel( |
| 6661 unsigned service_id, | 6668 unsigned service_id, |
| 6662 unsigned bind_target, | 6669 unsigned bind_target, |
| 6663 unsigned target, | 6670 unsigned target, |
| 6664 int level, | 6671 int level, |
| 6665 unsigned format, | 6672 unsigned format, |
| 6666 unsigned type, | 6673 unsigned type, |
| 6667 int width, | 6674 int width, |
| 6668 int height, | 6675 int height, |
| 6669 bool is_texture_immutable) { | 6676 bool is_texture_immutable) { |
| 6677 uint32 channels = GLES2Util::GetChannelsForFormat(format); |
| 6678 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) { |
| 6679 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D |
| 6680 // on depth formats. |
| 6681 GLuint fb = 0; |
| 6682 glGenFramebuffersEXT(1, &fb); |
| 6683 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb); |
| 6684 |
| 6685 bool have_stencil = (channels & GLES2Util::kStencil) != 0; |
| 6686 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : |
| 6687 GL_DEPTH_ATTACHMENT; |
| 6688 |
| 6689 glFramebufferTexture2DEXT( |
| 6690 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level); |
| 6691 // ANGLE promises a depth only attachment ok. |
| 6692 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) != |
| 6693 GL_FRAMEBUFFER_COMPLETE) { |
| 6694 return false; |
| 6695 } |
| 6696 glClearStencil(0); |
| 6697 glStencilMask(-1); |
| 6698 glClearDepth(1.0f); |
| 6699 glDepthMask(true); |
| 6700 glDisable(GL_SCISSOR_TEST); |
| 6701 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0)); |
| 6702 |
| 6703 RestoreClearState(); |
| 6704 |
| 6705 glDeleteFramebuffersEXT(1, &fb); |
| 6706 FramebufferManager::FramebufferInfo* framebuffer = |
| 6707 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); |
| 6708 GLuint fb_service_id = |
| 6709 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId(); |
| 6710 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id); |
| 6711 return true; |
| 6712 } |
| 6713 |
| 6670 static const uint32 kMaxZeroSize = 1024 * 1024 * 4; | 6714 static const uint32 kMaxZeroSize = 1024 * 1024 * 4; |
| 6671 | 6715 |
| 6672 uint32 size; | 6716 uint32 size; |
| 6673 uint32 padded_row_size; | 6717 uint32 padded_row_size; |
| 6674 if (!GLES2Util::ComputeImageDataSizes( | 6718 if (!GLES2Util::ComputeImageDataSizes( |
| 6675 width, height, format, type, unpack_alignment_, &size, | 6719 width, height, format, type, unpack_alignment_, &size, |
| 6676 NULL, &padded_row_size)) { | 6720 NULL, &padded_row_size)) { |
| 6677 return false; | 6721 return false; |
| 6678 } | 6722 } |
| 6679 | 6723 |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6887 } | 6931 } |
| 6888 if (imageSize < 0) { | 6932 if (imageSize < 0) { |
| 6889 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D: imageSize < 0"); | 6933 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D: imageSize < 0"); |
| 6890 return error::kNoError; | 6934 return error::kNoError; |
| 6891 } | 6935 } |
| 6892 DoCompressedTexSubImage2D( | 6936 DoCompressedTexSubImage2D( |
| 6893 target, level, xoffset, yoffset, width, height, format, imageSize, data); | 6937 target, level, xoffset, yoffset, width, height, format, imageSize, data); |
| 6894 return error::kNoError; | 6938 return error::kNoError; |
| 6895 } | 6939 } |
| 6896 | 6940 |
| 6941 bool GLES2DecoderImpl::ValidateTextureParameters( |
| 6942 const char* function_name, |
| 6943 GLenum target, GLenum format, GLenum type, GLint level) { |
| 6944 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) { |
| 6945 SetGLError(GL_INVALID_OPERATION, |
| 6946 (std::string(function_name) + ": invalid type " + |
| 6947 GLES2Util::GetStringEnum(type) + " for format " + |
| 6948 GLES2Util::GetStringEnum(format)).c_str()); |
| 6949 return false; |
| 6950 } |
| 6951 |
| 6952 uint32 channels = GLES2Util::GetChannelsForFormat(format); |
| 6953 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) { |
| 6954 SetGLError(GL_INVALID_OPERATION, |
| 6955 (std::string(function_name) + ": invalid type " + |
| 6956 GLES2Util::GetStringEnum(type) + " for format " + |
| 6957 GLES2Util::GetStringEnum(format)).c_str()); |
| 6958 return false; |
| 6959 } |
| 6960 return true; |
| 6961 } |
| 6962 |
| 6897 error::Error GLES2DecoderImpl::DoTexImage2D( | 6963 error::Error GLES2DecoderImpl::DoTexImage2D( |
| 6898 GLenum target, | 6964 GLenum target, |
| 6899 GLint level, | 6965 GLint level, |
| 6900 GLenum internal_format, | 6966 GLenum internal_format, |
| 6901 GLsizei width, | 6967 GLsizei width, |
| 6902 GLsizei height, | 6968 GLsizei height, |
| 6903 GLint border, | 6969 GLint border, |
| 6904 GLenum format, | 6970 GLenum format, |
| 6905 GLenum type, | 6971 GLenum type, |
| 6906 const void* pixels, | 6972 const void* pixels, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 6919 return error::kNoError; | 6985 return error::kNoError; |
| 6920 } | 6986 } |
| 6921 if (!validators_->pixel_type.IsValid(type)) { | 6987 if (!validators_->pixel_type.IsValid(type)) { |
| 6922 SetGLError(GL_INVALID_ENUM, "glTexImage2D: type GL_INVALID_ENUM"); | 6988 SetGLError(GL_INVALID_ENUM, "glTexImage2D: type GL_INVALID_ENUM"); |
| 6923 return error::kNoError; | 6989 return error::kNoError; |
| 6924 } | 6990 } |
| 6925 if (format != internal_format) { | 6991 if (format != internal_format) { |
| 6926 SetGLError(GL_INVALID_OPERATION, "glTexImage2D: format != internalFormat"); | 6992 SetGLError(GL_INVALID_OPERATION, "glTexImage2D: format != internalFormat"); |
| 6927 return error::kNoError; | 6993 return error::kNoError; |
| 6928 } | 6994 } |
| 6995 if (!ValidateTextureParameters("glTexImage2D", target, format, type, level)) { |
| 6996 return error::kNoError; |
| 6997 } |
| 6929 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || | 6998 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || |
| 6930 border != 0) { | 6999 border != 0) { |
| 6931 SetGLError(GL_INVALID_VALUE, "glTexImage2D: dimensions out of range"); | 7000 SetGLError(GL_INVALID_VALUE, "glTexImage2D: dimensions out of range"); |
| 6932 return error::kNoError; | 7001 return error::kNoError; |
| 6933 } | 7002 } |
| 7003 if ((GLES2Util::GetChannelsForFormat(format) & |
| 7004 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) { |
| 7005 SetGLError( |
| 7006 GL_INVALID_OPERATION, |
| 7007 "glTexImage2D: can not supply data for depth or stencil textures"); |
| 7008 return error::kNoError; |
| 7009 } |
| 6934 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | 7010 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
| 6935 if (!info) { | 7011 if (!info) { |
| 6936 SetGLError(GL_INVALID_OPERATION, | 7012 SetGLError(GL_INVALID_OPERATION, |
| 6937 "glTexImage2D: unknown texture for target"); | 7013 "glTexImage2D: unknown texture for target"); |
| 6938 return error::kNoError; | 7014 return error::kNoError; |
| 6939 } | 7015 } |
| 6940 | 7016 |
| 6941 if (info->IsImmutable()) { | 7017 if (info->IsImmutable()) { |
| 6942 SetGLError(GL_INVALID_OPERATION, | 7018 SetGLError(GL_INVALID_OPERATION, |
| 6943 "glTexImage2D: texture is immutable"); | 7019 "glTexImage2D: texture is immutable"); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7130 } | 7206 } |
| 7131 if (info->IsImmutable()) { | 7207 if (info->IsImmutable()) { |
| 7132 SetGLError(GL_INVALID_OPERATION, | 7208 SetGLError(GL_INVALID_OPERATION, |
| 7133 "glCopyTexImage2D: texture is immutable"); | 7209 "glCopyTexImage2D: texture is immutable"); |
| 7134 } | 7210 } |
| 7135 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || | 7211 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || |
| 7136 border != 0) { | 7212 border != 0) { |
| 7137 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D: dimensions out of range"); | 7213 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D: dimensions out of range"); |
| 7138 return; | 7214 return; |
| 7139 } | 7215 } |
| 7216 if (!ValidateTextureParameters( |
| 7217 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) { |
| 7218 return; |
| 7219 } |
| 7140 | 7220 |
| 7141 // Check we have compatible formats. | 7221 // Check we have compatible formats. |
| 7142 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); | 7222 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); |
| 7143 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); | 7223 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); |
| 7144 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format); | 7224 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format); |
| 7145 | 7225 |
| 7146 if ((channels_needed & channels_exist) != channels_needed) { | 7226 if ((channels_needed & channels_exist) != channels_needed) { |
| 7147 SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D: incompatible format"); | 7227 SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D: incompatible format"); |
| 7148 return; | 7228 return; |
| 7149 } | 7229 } |
| 7150 | 7230 |
| 7231 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { |
| 7232 SetGLError( |
| 7233 GL_INVALID_OPERATION, |
| 7234 "glCopyImage2D: can not be used with depth or stencil textures"); |
| 7235 return; |
| 7236 } |
| 7237 |
| 7151 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) { | 7238 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) { |
| 7152 return; | 7239 return; |
| 7153 } | 7240 } |
| 7154 | 7241 |
| 7155 CopyRealGLErrorsToWrapper(); | 7242 CopyRealGLErrorsToWrapper(); |
| 7156 ScopedResolvedFrameBufferBinder binder(this, false, true); | 7243 ScopedResolvedFrameBufferBinder binder(this, false, true); |
| 7157 gfx::Size size = GetBoundReadFrameBufferSize(); | 7244 gfx::Size size = GetBoundReadFrameBufferSize(); |
| 7158 | 7245 |
| 7159 if (info->IsAttachedToFramebuffer()) { | 7246 if (info->IsAttachedToFramebuffer()) { |
| 7160 state_dirty_ = true; | 7247 state_dirty_ = true; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7233 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); | 7320 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); |
| 7234 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); | 7321 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); |
| 7235 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format); | 7322 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format); |
| 7236 | 7323 |
| 7237 if ((channels_needed & channels_exist) != channels_needed) { | 7324 if ((channels_needed & channels_exist) != channels_needed) { |
| 7238 SetGLError( | 7325 SetGLError( |
| 7239 GL_INVALID_OPERATION, "glCopyTexSubImage2D: incompatible format"); | 7326 GL_INVALID_OPERATION, "glCopyTexSubImage2D: incompatible format"); |
| 7240 return; | 7327 return; |
| 7241 } | 7328 } |
| 7242 | 7329 |
| 7330 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { |
| 7331 SetGLError( |
| 7332 GL_INVALID_OPERATION, |
| 7333 "glCopySubImage2D: can not be used with depth or stencil textures"); |
| 7334 return; |
| 7335 } |
| 7336 |
| 7243 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) { | 7337 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) { |
| 7244 return; | 7338 return; |
| 7245 } | 7339 } |
| 7246 | 7340 |
| 7247 ScopedResolvedFrameBufferBinder binder(this, false, true); | 7341 ScopedResolvedFrameBufferBinder binder(this, false, true); |
| 7248 gfx::Size size = GetBoundReadFrameBufferSize(); | 7342 gfx::Size size = GetBoundReadFrameBufferSize(); |
| 7249 GLint copyX = 0; | 7343 GLint copyX = 0; |
| 7250 GLint copyY = 0; | 7344 GLint copyY = 0; |
| 7251 GLint copyWidth = 0; | 7345 GLint copyWidth = 0; |
| 7252 GLint copyHeight = 0; | 7346 GLint copyHeight = 0; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7323 return; | 7417 return; |
| 7324 } | 7418 } |
| 7325 | 7419 |
| 7326 if (!info->ValidForTexture( | 7420 if (!info->ValidForTexture( |
| 7327 target, level, xoffset, yoffset, width, height, format, type)) { | 7421 target, level, xoffset, yoffset, width, height, format, type)) { |
| 7328 SetGLError(GL_INVALID_VALUE, | 7422 SetGLError(GL_INVALID_VALUE, |
| 7329 "glTexSubImage2D: bad dimensions."); | 7423 "glTexSubImage2D: bad dimensions."); |
| 7330 return; | 7424 return; |
| 7331 } | 7425 } |
| 7332 | 7426 |
| 7427 if ((GLES2Util::GetChannelsForFormat(format) & |
| 7428 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { |
| 7429 SetGLError( |
| 7430 GL_INVALID_OPERATION, |
| 7431 "glTexSubImage2D: can not supply data for depth or stencil textures"); |
| 7432 return; |
| 7433 } |
| 7434 |
| 7333 GLsizei tex_width = 0; | 7435 GLsizei tex_width = 0; |
| 7334 GLsizei tex_height = 0; | 7436 GLsizei tex_height = 0; |
| 7335 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); | 7437 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); |
| 7336 DCHECK(ok); | 7438 DCHECK(ok); |
| 7337 if (xoffset != 0 || yoffset != 0 || | 7439 if (xoffset != 0 || yoffset != 0 || |
| 7338 width != tex_width || height != tex_height) { | 7440 width != tex_width || height != tex_height) { |
| 7339 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { | 7441 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { |
| 7340 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D: dimensions too big"); | 7442 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D: dimensions too big"); |
| 7341 return; | 7443 return; |
| 7342 } | 7444 } |
| (...skipping 1399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8742 BindAndApplyTextureParameters(info); | 8844 BindAndApplyTextureParameters(info); |
| 8743 } | 8845 } |
| 8744 | 8846 |
| 8745 // Include the auto-generated part of this file. We split this because it means | 8847 // Include the auto-generated part of this file. We split this because it means |
| 8746 // we can easily edit the non-auto generated parts right here in this file | 8848 // we can easily edit the non-auto generated parts right here in this file |
| 8747 // instead of having to edit some template or the code generator. | 8849 // instead of having to edit some template or the code generator. |
| 8748 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 8850 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 8749 | 8851 |
| 8750 } // namespace gles2 | 8852 } // namespace gles2 |
| 8751 } // namespace gpu | 8853 } // namespace gpu |
| OLD | NEW |