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 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 855 | 855 |
| 856 GLsizei GetBoundFramebufferSamples(GLenum target); | 856 GLsizei GetBoundFramebufferSamples(GLenum target); |
| 857 | 857 |
| 858 // Return 0 if no depth attachment. | 858 // Return 0 if no depth attachment. |
| 859 GLenum GetBoundFramebufferDepthFormat(GLenum target); | 859 GLenum GetBoundFramebufferDepthFormat(GLenum target); |
| 860 // Return 0 if no stencil attachment. | 860 // Return 0 if no stencil attachment. |
| 861 GLenum GetBoundFramebufferStencilFormat(GLenum target); | 861 GLenum GetBoundFramebufferStencilFormat(GLenum target); |
| 862 | 862 |
| 863 void MarkDrawBufferAsCleared(GLenum buffer, GLint drawbuffer_i); | 863 void MarkDrawBufferAsCleared(GLenum buffer, GLint drawbuffer_i); |
| 864 | 864 |
| 865 // Wrapper for CompressedTexImage2D commands. | 865 // Wrapper for CompressedTexImage{2|3}D commands. |
| 866 error::Error DoCompressedTexImage2D( | 866 error::Error DoCompressedTexImage( |
| 867 GLenum target, | 867 GLenum target, |
| 868 GLint level, | 868 GLint level, |
| 869 GLenum internal_format, | 869 GLenum internal_format, |
| 870 GLsizei width, | |
| 871 GLsizei height, | |
| 872 GLint border, | |
| 873 GLsizei image_size, | |
| 874 const void* data); | |
| 875 | |
| 876 // Wrapper for CompressedTexImage3D commands. | |
| 877 error::Error DoCompressedTexImage3D( | |
| 878 GLenum target, | |
| 879 GLint level, | |
| 880 GLenum internal_format, | |
| 881 GLsizei width, | 870 GLsizei width, |
| 882 GLsizei height, | 871 GLsizei height, |
| 883 GLsizei depth, | 872 GLsizei depth, |
| 884 GLint border, | 873 GLint border, |
| 885 GLsizei image_size, | 874 GLsizei image_size, |
| 886 const void* data); | 875 const void* data, |
| 876 ContextState::Dimension dimension); | |
| 887 | 877 |
| 888 // Wrapper for CompressedTexSubImage2D. | 878 // Wrapper for CompressedTexSubImage{2|3}D. |
| 889 void DoCompressedTexSubImage2D( | 879 error::Error DoCompressedTexSubImage( |
| 890 GLenum target, | 880 GLenum target, |
| 891 GLint level, | 881 GLint level, |
| 892 GLint xoffset, | 882 GLint xoffset, |
| 893 GLint yoffset, | |
| 894 GLsizei width, | |
| 895 GLsizei height, | |
| 896 GLenum format, | |
| 897 GLsizei imageSize, | |
| 898 const void* data); | |
| 899 | |
| 900 // Wrapper for CompressedTexSubImage3D. | |
| 901 void DoCompressedTexSubImage3D( | |
| 902 GLenum target, | |
| 903 GLint level, | |
| 904 GLint xoffset, | |
| 905 GLint yoffset, | 883 GLint yoffset, |
| 906 GLint zoffset, | 884 GLint zoffset, |
| 907 GLsizei width, | 885 GLsizei width, |
| 908 GLsizei height, | 886 GLsizei height, |
| 909 GLsizei depth, | 887 GLsizei depth, |
| 910 GLenum format, | 888 GLenum format, |
| 911 GLsizei image_size, | 889 GLsizei imageSize, |
| 912 const void* data); | 890 const void* data, |
| 891 ContextState::Dimension dimension); | |
| 913 | 892 |
| 914 // Validate if |format| is valid for CopyTex{Sub}Image functions. | 893 // Validate if |format| is valid for CopyTex{Sub}Image functions. |
| 915 // If not, generate a GL error and return false. | 894 // If not, generate a GL error and return false. |
| 916 bool ValidateCopyTexFormat(const char* func_name, GLenum internal_format, | 895 bool ValidateCopyTexFormat(const char* func_name, GLenum internal_format, |
| 917 GLenum read_format, GLenum read_type); | 896 GLenum read_format, GLenum read_type); |
| 918 | 897 |
| 919 // Wrapper for CopyTexImage2D. | 898 // Wrapper for CopyTexImage2D. |
| 920 void DoCopyTexImage2D( | 899 void DoCopyTexImage2D( |
| 921 GLenum target, | 900 GLenum target, |
| 922 GLint level, | 901 GLint level, |
| (...skipping 12125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13048 GLenum internal_format = static_cast<GLenum>(c.internalformat); | 13027 GLenum internal_format = static_cast<GLenum>(c.internalformat); |
| 13049 GLsizei width = static_cast<GLsizei>(c.width); | 13028 GLsizei width = static_cast<GLsizei>(c.width); |
| 13050 GLsizei height = static_cast<GLsizei>(c.height); | 13029 GLsizei height = static_cast<GLsizei>(c.height); |
| 13051 GLuint bucket_id = static_cast<GLuint>(c.bucket_id); | 13030 GLuint bucket_id = static_cast<GLuint>(c.bucket_id); |
| 13052 GLint border = static_cast<GLint>(c.border); | 13031 GLint border = static_cast<GLint>(c.border); |
| 13053 Bucket* bucket = GetBucket(bucket_id); | 13032 Bucket* bucket = GetBucket(bucket_id); |
| 13054 if (!bucket) | 13033 if (!bucket) |
| 13055 return error::kInvalidArguments; | 13034 return error::kInvalidArguments; |
| 13056 uint32_t image_size = bucket->size(); | 13035 uint32_t image_size = bucket->size(); |
| 13057 const void* data = bucket->GetData(0, image_size); | 13036 const void* data = bucket->GetData(0, image_size); |
| 13058 DCHECK(data || !image_size); | 13037 DCHECK(data || !image_size); |
|
piman
2016/10/26 21:53:22
Oh, I forgot one thing in the previous review - an
Zhenyao Mo
2016/10/26 22:31:58
Good catch. Added.
| |
| 13059 return DoCompressedTexImage2D(target, level, internal_format, width, height, | 13038 return DoCompressedTexImage(target, level, internal_format, width, height, 1, |
| 13060 border, image_size, data); | 13039 border, image_size, data, ContextState::k2D); |
| 13061 } | 13040 } |
| 13062 | 13041 |
| 13063 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D( | 13042 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D( |
| 13064 uint32_t immediate_data_size, const volatile void* cmd_data) { | 13043 uint32_t immediate_data_size, const volatile void* cmd_data) { |
| 13065 const volatile gles2::cmds::CompressedTexImage2D& c = | 13044 const volatile gles2::cmds::CompressedTexImage2D& c = |
| 13066 *static_cast<const volatile gles2::cmds::CompressedTexImage2D*>(cmd_data); | 13045 *static_cast<const volatile gles2::cmds::CompressedTexImage2D*>(cmd_data); |
| 13067 GLenum target = static_cast<GLenum>(c.target); | 13046 GLenum target = static_cast<GLenum>(c.target); |
| 13068 GLint level = static_cast<GLint>(c.level); | 13047 GLint level = static_cast<GLint>(c.level); |
| 13069 GLenum internal_format = static_cast<GLenum>(c.internalformat); | 13048 GLenum internal_format = static_cast<GLenum>(c.internalformat); |
| 13070 GLsizei width = static_cast<GLsizei>(c.width); | 13049 GLsizei width = static_cast<GLsizei>(c.width); |
| 13071 GLsizei height = static_cast<GLsizei>(c.height); | 13050 GLsizei height = static_cast<GLsizei>(c.height); |
| 13072 GLint border = static_cast<GLint>(c.border); | 13051 GLint border = static_cast<GLint>(c.border); |
| 13073 GLsizei image_size = static_cast<GLsizei>(c.imageSize); | 13052 GLsizei image_size = static_cast<GLsizei>(c.imageSize); |
| 13074 uint32_t data_size = image_size; | |
| 13075 uint32_t data_shm_id = c.data_shm_id; | 13053 uint32_t data_shm_id = c.data_shm_id; |
| 13076 uint32_t data_shm_offset = c.data_shm_offset; | 13054 uint32_t data_shm_offset = c.data_shm_offset; |
| 13077 | 13055 |
| 13078 const void* data; | 13056 const void* data; |
| 13079 if (state_.bound_pixel_unpack_buffer.get()) { | 13057 if (state_.bound_pixel_unpack_buffer.get()) { |
| 13080 if (data_shm_id) { | 13058 if (data_shm_id) { |
| 13081 return error::kInvalidArguments; | 13059 return error::kInvalidArguments; |
| 13082 } | 13060 } |
| 13083 data = reinterpret_cast<const void*>(data_shm_offset); | 13061 data = reinterpret_cast<const void*>(data_shm_offset); |
| 13084 } else { | 13062 } else { |
| 13085 if (!data_shm_id && data_shm_offset) { | 13063 if (!data_shm_id && data_shm_offset) { |
| 13086 return error::kInvalidArguments; | 13064 return error::kInvalidArguments; |
| 13087 } | 13065 } |
| 13088 data = GetSharedMemoryAs<const void*>( | 13066 data = GetSharedMemoryAs<const void*>( |
| 13089 data_shm_id, data_shm_offset, data_size); | 13067 data_shm_id, data_shm_offset, image_size); |
| 13090 } | 13068 } |
| 13091 return DoCompressedTexImage2D(target, level, internal_format, width, height, | 13069 return DoCompressedTexImage(target, level, internal_format, width, height, 1, |
| 13092 border, image_size, data); | 13070 border, image_size, data, ContextState::k2D); |
| 13093 } | 13071 } |
| 13094 | 13072 |
| 13095 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( | 13073 error::Error GLES2DecoderImpl::HandleCompressedTexImage3DBucket( |
| 13074 uint32_t immediate_data_size, const volatile void* cmd_data) { | |
| 13075 if (!unsafe_es3_apis_enabled()) | |
| 13076 return error::kUnknownCommand; | |
| 13077 const volatile gles2::cmds::CompressedTexImage3DBucket& c = | |
| 13078 *static_cast<const volatile gles2::cmds::CompressedTexImage3DBucket*>( | |
| 13079 cmd_data); | |
| 13080 GLenum target = static_cast<GLenum>(c.target); | |
| 13081 GLint level = static_cast<GLint>(c.level); | |
| 13082 GLenum internal_format = static_cast<GLenum>(c.internalformat); | |
| 13083 GLsizei width = static_cast<GLsizei>(c.width); | |
| 13084 GLsizei height = static_cast<GLsizei>(c.height); | |
| 13085 GLsizei depth = static_cast<GLsizei>(c.depth); | |
| 13086 GLuint bucket_id = static_cast<GLuint>(c.bucket_id); | |
| 13087 GLint border = static_cast<GLint>(c.border); | |
| 13088 Bucket* bucket = GetBucket(bucket_id); | |
| 13089 if (!bucket) | |
| 13090 return error::kInvalidArguments; | |
| 13091 uint32_t image_size = bucket->size(); | |
| 13092 const void* data = bucket->GetData(0, image_size); | |
| 13093 DCHECK(data || !image_size); | |
| 13094 return DoCompressedTexImage(target, level, internal_format, width, height, | |
| 13095 depth, border, image_size, data, | |
| 13096 ContextState::k3D); | |
| 13097 } | |
| 13098 | |
| 13099 error::Error GLES2DecoderImpl::HandleCompressedTexImage3D( | |
| 13100 uint32_t immediate_data_size, const volatile void* cmd_data) { | |
| 13101 if (!unsafe_es3_apis_enabled()) | |
| 13102 return error::kUnknownCommand; | |
| 13103 const volatile gles2::cmds::CompressedTexImage3D& c = | |
| 13104 *static_cast<const volatile gles2::cmds::CompressedTexImage3D*>(cmd_data); | |
| 13105 GLenum target = static_cast<GLenum>(c.target); | |
| 13106 GLint level = static_cast<GLint>(c.level); | |
| 13107 GLenum internal_format = static_cast<GLenum>(c.internalformat); | |
| 13108 GLsizei width = static_cast<GLsizei>(c.width); | |
| 13109 GLsizei height = static_cast<GLsizei>(c.height); | |
| 13110 GLsizei depth = static_cast<GLsizei>(c.depth); | |
| 13111 GLint border = static_cast<GLint>(c.border); | |
| 13112 GLsizei image_size = static_cast<GLsizei>(c.imageSize); | |
| 13113 uint32_t data_shm_id = c.data_shm_id; | |
| 13114 uint32_t data_shm_offset = c.data_shm_offset; | |
| 13115 | |
| 13116 const void* data; | |
| 13117 if (state_.bound_pixel_unpack_buffer.get()) { | |
| 13118 if (data_shm_id) { | |
| 13119 return error::kInvalidArguments; | |
| 13120 } | |
| 13121 data = reinterpret_cast<const void*>(data_shm_offset); | |
| 13122 } else { | |
| 13123 if (!data_shm_id && data_shm_offset) { | |
| 13124 return error::kInvalidArguments; | |
| 13125 } | |
| 13126 data = GetSharedMemoryAs<const void*>( | |
| 13127 data_shm_id, data_shm_offset, image_size); | |
| 13128 } | |
| 13129 return DoCompressedTexImage(target, level, internal_format, width, height, | |
| 13130 depth, border, image_size, data, | |
| 13131 ContextState::k3D); | |
| 13132 } | |
| 13133 | |
| 13134 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage3DBucket( | |
| 13135 uint32_t immediate_data_size, const volatile void* cmd_data) { | |
| 13136 if (!unsafe_es3_apis_enabled()) | |
| 13137 return error::kUnknownCommand; | |
| 13138 const volatile gles2::cmds::CompressedTexSubImage3DBucket& c = | |
| 13139 *static_cast<const volatile gles2::cmds::CompressedTexSubImage3DBucket*>( | |
| 13140 cmd_data); | |
| 13141 GLenum target = static_cast<GLenum>(c.target); | |
| 13142 GLint level = static_cast<GLint>(c.level); | |
| 13143 GLint xoffset = static_cast<GLint>(c.xoffset); | |
| 13144 GLint yoffset = static_cast<GLint>(c.yoffset); | |
| 13145 GLint zoffset = static_cast<GLint>(c.zoffset); | |
| 13146 GLsizei width = static_cast<GLsizei>(c.width); | |
| 13147 GLsizei height = static_cast<GLsizei>(c.height); | |
| 13148 GLsizei depth = static_cast<GLsizei>(c.depth); | |
| 13149 GLenum format = static_cast<GLenum>(c.format); | |
| 13150 GLuint bucket_id = static_cast<GLuint>(c.bucket_id); | |
| 13151 Bucket* bucket = GetBucket(bucket_id); | |
| 13152 if (!bucket) | |
| 13153 return error::kInvalidArguments; | |
| 13154 uint32_t image_size = bucket->size(); | |
| 13155 const void* data = bucket->GetData(0, image_size); | |
| 13156 DCHECK(data || !image_size); | |
| 13157 return DoCompressedTexSubImage(target, level, xoffset, yoffset, zoffset, | |
| 13158 width, height, depth, format, image_size, | |
| 13159 data, ContextState::k3D); | |
| 13160 } | |
| 13161 | |
| 13162 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage3D( | |
| 13163 uint32_t immediate_data_size, const volatile void* cmd_data) { | |
| 13164 if (!unsafe_es3_apis_enabled()) | |
| 13165 return error::kUnknownCommand; | |
| 13166 const volatile gles2::cmds::CompressedTexSubImage3D& c = | |
| 13167 *static_cast<const volatile gles2::cmds::CompressedTexSubImage3D*>( | |
| 13168 cmd_data); | |
| 13169 GLenum target = static_cast<GLenum>(c.target); | |
| 13170 GLint level = static_cast<GLint>(c.level); | |
| 13171 GLint xoffset = static_cast<GLint>(c.xoffset); | |
| 13172 GLint yoffset = static_cast<GLint>(c.yoffset); | |
| 13173 GLint zoffset = static_cast<GLint>(c.zoffset); | |
| 13174 GLsizei width = static_cast<GLsizei>(c.width); | |
| 13175 GLsizei height = static_cast<GLsizei>(c.height); | |
| 13176 GLsizei depth = static_cast<GLsizei>(c.depth); | |
| 13177 GLenum format = static_cast<GLenum>(c.format); | |
| 13178 GLsizei image_size = static_cast<GLsizei>(c.imageSize); | |
| 13179 uint32_t data_shm_id = c.data_shm_id; | |
| 13180 uint32_t data_shm_offset = c.data_shm_offset; | |
| 13181 | |
| 13182 const void* data; | |
| 13183 if (state_.bound_pixel_unpack_buffer.get()) { | |
| 13184 if (data_shm_id) { | |
| 13185 return error::kInvalidArguments; | |
| 13186 } | |
| 13187 data = reinterpret_cast<const void*>(data_shm_offset); | |
| 13188 } else { | |
| 13189 if (!data_shm_id && data_shm_offset) { | |
| 13190 return error::kInvalidArguments; | |
| 13191 } | |
| 13192 data = GetSharedMemoryAs<const void*>( | |
| 13193 data_shm_id, data_shm_offset, image_size); | |
| 13194 } | |
| 13195 return DoCompressedTexSubImage(target, level, xoffset, yoffset, zoffset, | |
| 13196 width, height, depth, format, image_size, | |
| 13197 data, ContextState::k3D); | |
| 13198 } | |
| 13199 | |
| 13200 error::Error GLES2DecoderImpl::DoCompressedTexImage( | |
| 13096 GLenum target, GLint level, GLenum internal_format, GLsizei width, | 13201 GLenum target, GLint level, GLenum internal_format, GLsizei width, |
| 13097 GLsizei height, GLint border, GLsizei image_size, const void* data) { | 13202 GLsizei height, GLsizei depth, GLint border, GLsizei image_size, |
| 13098 const char* func_name = "glCompressedTexImage2D"; | 13203 const void* data, ContextState::Dimension dimension) { |
| 13099 if (!validators_->texture_target.IsValid(target)) { | 13204 const char* func_name; |
| 13100 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); | 13205 if (dimension == ContextState::k2D) { |
| 13101 return error::kNoError; | 13206 func_name = "glCompressedTexImage2D"; |
| 13102 } | 13207 if (!validators_->texture_target.IsValid(target)) { |
| 13103 // TODO(ccameron): Add a separate texture from |texture_target| for | 13208 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); |
| 13104 // [Compressed]Tex[Sub]Image2D and related functions. | 13209 return error::kNoError; |
| 13105 // http://crbug.com/536854 | 13210 } |
| 13106 if (target == GL_TEXTURE_RECTANGLE_ARB) { | 13211 // TODO(ccameron): Add a separate texture from |texture_target| for |
| 13107 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); | 13212 // [Compressed]Tex[Sub]Image2D and related functions. |
| 13108 return error::kNoError; | 13213 // http://crbug.com/536854 |
| 13214 if (target == GL_TEXTURE_RECTANGLE_ARB) { | |
| 13215 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); | |
| 13216 return error::kNoError; | |
| 13217 } | |
| 13218 } else { | |
| 13219 DCHECK_EQ(ContextState::k3D, dimension); | |
| 13220 func_name = "glCompressedTexImage3D"; | |
| 13221 if (!validators_->texture_3_d_target.IsValid(target)) { | |
| 13222 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); | |
| 13223 return error::kNoError; | |
| 13224 } | |
| 13109 } | 13225 } |
| 13110 if (!validators_->compressed_texture_format.IsValid(internal_format)) { | 13226 if (!validators_->compressed_texture_format.IsValid(internal_format)) { |
| 13111 LOCAL_SET_GL_ERROR_INVALID_ENUM( | 13227 LOCAL_SET_GL_ERROR_INVALID_ENUM( |
| 13112 func_name, internal_format, "internalformat"); | 13228 func_name, internal_format, "internalformat"); |
| 13113 return error::kNoError; | 13229 return error::kNoError; |
| 13114 } | 13230 } |
| 13115 if (image_size < 0) { | 13231 if (image_size < 0) { |
| 13116 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "imageSize < 0"); | 13232 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "imageSize < 0"); |
| 13117 return error::kNoError; | 13233 return error::kNoError; |
| 13118 } | 13234 } |
| 13119 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || | 13235 if (!texture_manager()->ValidForTarget(target, level, width, height, depth) || |
| 13120 border != 0) { | 13236 border != 0) { |
| 13121 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range"); | 13237 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range"); |
| 13122 return error::kNoError; | 13238 return error::kNoError; |
| 13123 } | 13239 } |
| 13124 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( | 13240 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( |
| 13125 &state_, target); | 13241 &state_, target); |
| 13126 if (!texture_ref) { | 13242 if (!texture_ref) { |
| 13127 LOCAL_SET_GL_ERROR( | 13243 LOCAL_SET_GL_ERROR( |
| 13128 GL_INVALID_VALUE, func_name, "no texture bound at target"); | 13244 GL_INVALID_VALUE, func_name, "no texture bound at target"); |
| 13129 return error::kNoError; | 13245 return error::kNoError; |
| 13130 } | 13246 } |
| 13131 Texture* texture = texture_ref->texture(); | 13247 Texture* texture = texture_ref->texture(); |
| 13132 if (texture->IsImmutable()) { | 13248 if (texture->IsImmutable()) { |
| 13133 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "texture is immutable"); | 13249 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "texture is immutable"); |
| 13134 return error::kNoError; | 13250 return error::kNoError; |
| 13135 } | 13251 } |
| 13252 | |
| 13136 if (!ValidateCompressedTexDimensions(func_name, target, level, | 13253 if (!ValidateCompressedTexDimensions(func_name, target, level, |
| 13137 width, height, 1, internal_format) || | 13254 width, height, depth, internal_format) || |
| 13138 !ValidateCompressedTexFuncData(func_name, width, height, 1, | 13255 !ValidateCompressedTexFuncData(func_name, width, height, depth, |
| 13139 internal_format, image_size, data)) { | 13256 internal_format, image_size, data)) { |
| 13140 return error::kNoError; | 13257 return error::kNoError; |
| 13141 } | 13258 } |
| 13142 | 13259 |
| 13143 if (!EnsureGPUMemoryAvailable(image_size)) { | 13260 if (!EnsureGPUMemoryAvailable(image_size)) { |
| 13144 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "out of memory"); | 13261 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "out of memory"); |
| 13145 return error::kNoError; | 13262 return error::kNoError; |
| 13146 } | 13263 } |
| 13147 | 13264 |
| 13148 if (texture->IsAttachedToFramebuffer()) { | 13265 if (texture->IsAttachedToFramebuffer()) { |
| 13149 framebuffer_state_.clear_state_dirty = true; | 13266 framebuffer_state_.clear_state_dirty = true; |
| 13150 } | 13267 } |
| 13151 | 13268 |
| 13152 std::unique_ptr<int8_t[]> zero; | 13269 std::unique_ptr<int8_t[]> zero; |
| 13153 if (!state_.bound_pixel_unpack_buffer && !data) { | 13270 if (!state_.bound_pixel_unpack_buffer && !data) { |
| 13154 zero.reset(new int8_t[image_size]); | 13271 zero.reset(new int8_t[image_size]); |
| 13155 memset(zero.get(), 0, image_size); | 13272 memset(zero.get(), 0, image_size); |
| 13156 data = zero.get(); | 13273 data = zero.get(); |
| 13157 } | 13274 } |
| 13158 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(func_name); | 13275 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(func_name); |
| 13159 | |
| 13160 const CompressedFormatInfo* format_info = | 13276 const CompressedFormatInfo* format_info = |
| 13161 GetCompressedFormatInfo(internal_format); | 13277 GetCompressedFormatInfo(internal_format); |
| 13162 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | 13278 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { |
| 13163 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( | |
| 13164 state_, *format_info, width, height, 1, image_size, data); | |
| 13165 if (!decompressed_data) { | |
| 13166 MarkContextLost(error::kGuilty); | |
| 13167 group_->LoseContexts(error::kInnocent); | |
| 13168 return error::kLostContext; | |
| 13169 } | |
| 13170 state_.PushTextureDecompressionUnpackState(); | |
| 13171 glTexImage2D(target, level, format_info->decompressed_internal_format, | |
| 13172 width, height, border, format_info->decompressed_format, | |
| 13173 format_info->decompressed_type, decompressed_data.get()); | |
| 13174 state_.RestoreUnpackState(); | |
| 13175 } else { | |
| 13176 glCompressedTexImage2D(target, level, internal_format, width, height, | |
| 13177 border, image_size, data); | |
| 13178 } | |
| 13179 GLenum error = LOCAL_PEEK_GL_ERROR(func_name); | |
| 13180 if (error == GL_NO_ERROR) { | |
| 13181 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, | |
| 13182 width, height, 1, border, 0, 0, | |
| 13183 gfx::Rect(width, height)); | |
| 13184 } | |
| 13185 | |
| 13186 // This may be a slow command. Exit command processing to allow for | |
| 13187 // context preemption and GPU watchdog checks. | |
| 13188 ExitCommandProcessingEarly(); | |
| 13189 return error::kNoError; | |
| 13190 } | |
| 13191 | |
| 13192 error::Error GLES2DecoderImpl::DoCompressedTexImage3D( | |
| 13193 GLenum target, | |
| 13194 GLint level, | |
| 13195 GLenum internal_format, | |
| 13196 GLsizei width, | |
| 13197 GLsizei height, | |
| 13198 GLsizei depth, | |
| 13199 GLint border, | |
| 13200 GLsizei image_size, | |
| 13201 const void* data) { | |
| 13202 if (!texture_manager()->ValidForTarget(target, level, width, height, depth) || | |
| 13203 border != 0) { | |
| 13204 LOCAL_SET_GL_ERROR( | |
| 13205 GL_INVALID_VALUE, | |
| 13206 "glCompressedTexImage3D", "dimensions out of range"); | |
| 13207 return error::kNoError; | |
| 13208 } | |
| 13209 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( | |
| 13210 &state_, target); | |
| 13211 if (!texture_ref) { | |
| 13212 LOCAL_SET_GL_ERROR( | |
| 13213 GL_INVALID_VALUE, | |
| 13214 "glCompressedTexImage3D", "unknown texture target"); | |
| 13215 return error::kNoError; | |
| 13216 } | |
| 13217 Texture* texture = texture_ref->texture(); | |
| 13218 if (texture->IsImmutable()) { | |
| 13219 LOCAL_SET_GL_ERROR( | |
| 13220 GL_INVALID_OPERATION, | |
| 13221 "glCompressedTexImage3D", "texture is immutable"); | |
| 13222 return error::kNoError; | |
| 13223 } | |
| 13224 | |
| 13225 if (!ValidateCompressedTexDimensions("glCompressedTexImage3D", target, level, | |
| 13226 width, height, depth, internal_format) || | |
| 13227 !ValidateCompressedTexFuncData("glCompressedTexImage3D", width, height, | |
| 13228 depth, internal_format, image_size, | |
| 13229 data)) { | |
| 13230 return error::kNoError; | |
| 13231 } | |
| 13232 | |
| 13233 if (!EnsureGPUMemoryAvailable(image_size)) { | |
| 13234 LOCAL_SET_GL_ERROR( | |
| 13235 GL_OUT_OF_MEMORY, "glCompressedTexImage3D", "out of memory"); | |
| 13236 return error::kNoError; | |
| 13237 } | |
| 13238 | |
| 13239 if (texture->IsAttachedToFramebuffer()) { | |
| 13240 framebuffer_state_.clear_state_dirty = true; | |
| 13241 } | |
| 13242 | |
| 13243 std::unique_ptr<int8_t[]> zero; | |
| 13244 if (!state_.bound_pixel_unpack_buffer && !data) { | |
| 13245 zero.reset(new int8_t[image_size]); | |
| 13246 memset(zero.get(), 0, image_size); | |
| 13247 data = zero.get(); | |
| 13248 } | |
| 13249 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D"); | |
| 13250 const CompressedFormatInfo* format_info = | |
| 13251 GetCompressedFormatInfo(internal_format); | |
| 13252 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | |
| 13253 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( | 13279 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( |
| 13254 state_, *format_info, width, height, depth, image_size, data); | 13280 state_, *format_info, width, height, depth, image_size, data); |
| 13255 if (!decompressed_data) { | 13281 if (!decompressed_data) { |
| 13256 MarkContextLost(error::kGuilty); | 13282 MarkContextLost(error::kGuilty); |
| 13257 group_->LoseContexts(error::kInnocent); | 13283 group_->LoseContexts(error::kInnocent); |
| 13258 return error::kLostContext; | 13284 return error::kLostContext; |
| 13259 } | 13285 } |
| 13260 state_.PushTextureDecompressionUnpackState(); | 13286 state_.PushTextureDecompressionUnpackState(); |
| 13261 glTexImage3D(target, level, format_info->decompressed_internal_format, | 13287 if (dimension == ContextState::k2D) { |
| 13262 width, height, depth, border, format_info->decompressed_format, | 13288 glTexImage2D(target, level, format_info->decompressed_internal_format, |
| 13263 format_info->decompressed_type, decompressed_data.get()); | 13289 width, height, border, format_info->decompressed_format, |
| 13290 format_info->decompressed_type, decompressed_data.get()); | |
| 13291 } else { | |
| 13292 glTexImage3D( | |
| 13293 target, level, format_info->decompressed_internal_format, | |
| 13294 width, height, depth, border, format_info->decompressed_format, | |
| 13295 format_info->decompressed_type, decompressed_data.get()); | |
| 13296 } | |
| 13264 state_.RestoreUnpackState(); | 13297 state_.RestoreUnpackState(); |
| 13265 } else { | 13298 } else { |
| 13266 glCompressedTexImage3D(target, level, internal_format, width, height, depth, | 13299 if (dimension == ContextState::k2D) { |
| 13267 border, image_size, data); | 13300 glCompressedTexImage2D(target, level, internal_format, width, height, |
| 13301 border, image_size, data); | |
| 13302 } else { | |
| 13303 glCompressedTexImage3D(target, level, internal_format, width, height, | |
| 13304 depth, border, image_size, data); | |
| 13305 } | |
| 13268 } | 13306 } |
| 13269 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D"); | 13307 GLenum error = LOCAL_PEEK_GL_ERROR(func_name); |
| 13270 if (error == GL_NO_ERROR) { | 13308 if (error == GL_NO_ERROR) { |
| 13271 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, | 13309 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, |
| 13272 width, height, depth, border, 0, 0, | 13310 width, height, depth, border, 0, 0, |
| 13273 gfx::Rect(width, height)); | 13311 gfx::Rect(width, height)); |
| 13274 } | 13312 } |
| 13275 | 13313 |
| 13276 // This may be a slow command. Exit command processing to allow for | 13314 // This may be a slow command. Exit command processing to allow for |
| 13277 // context preemption and GPU watchdog checks. | 13315 // context preemption and GPU watchdog checks. |
| 13278 ExitCommandProcessingEarly(); | 13316 ExitCommandProcessingEarly(); |
| 13279 return error::kNoError; | 13317 return error::kNoError; |
| 13280 } | 13318 } |
| 13281 | 13319 |
| 13282 void GLES2DecoderImpl::DoCompressedTexSubImage3D( | |
| 13283 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, | |
| 13284 GLsizei width, GLsizei height, GLsizei depth, GLenum format, | |
| 13285 GLsizei image_size, const void* data) { | |
| 13286 if (!texture_manager()->ValidForTarget(target, level, width, height, depth)) { | |
| 13287 LOCAL_SET_GL_ERROR( | |
| 13288 GL_INVALID_VALUE, | |
| 13289 "glCompressedTexSubImage3D", "dimensions out of range"); | |
| 13290 return; | |
| 13291 } | |
| 13292 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( | |
| 13293 &state_, target); | |
| 13294 if (!texture_ref) { | |
| 13295 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", | |
| 13296 "unknown texture for target"); | |
| 13297 return; | |
| 13298 } | |
| 13299 Texture* texture = texture_ref->texture(); | |
| 13300 GLenum type = 0, internal_format = 0; | |
| 13301 if (!texture->GetLevelType(target, level, &type, &internal_format)) { | |
| 13302 std::string msg = base::StringPrintf( | |
| 13303 "level %d does not exist", level); | |
| 13304 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", | |
| 13305 msg.c_str()); | |
| 13306 return; | |
| 13307 } | |
| 13308 if (internal_format != format) { | |
| 13309 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", | |
| 13310 "format does not match internal format"); | |
| 13311 return; | |
| 13312 } | |
| 13313 if (!texture->ValidForTexture(target, level, xoffset, yoffset, zoffset, | |
| 13314 width, height, depth)) { | |
| 13315 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedTexSubImage3D", | |
| 13316 "bad dimensions"); | |
| 13317 return; | |
| 13318 } | |
| 13319 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage3D", width, height, | |
| 13320 depth, format, image_size, data) || | |
| 13321 !ValidateCompressedTexSubDimensions( | |
| 13322 "glCompressedTexSubImage3D", target, level, xoffset, yoffset, zoffset, | |
| 13323 width, height, depth, format, texture)) { | |
| 13324 return; | |
| 13325 } | |
| 13326 | |
| 13327 // Note: There is no need to deal with texture cleared tracking here | |
| 13328 // because the validation above means you can only get here if the level | |
| 13329 // is already a matching compressed format and in that case | |
| 13330 // CompressedTexImage3D already cleared the texture. | |
| 13331 | |
| 13332 const CompressedFormatInfo* format_info = | |
| 13333 GetCompressedFormatInfo(internal_format); | |
| 13334 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | |
| 13335 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( | |
| 13336 state_, *format_info, width, height, depth, image_size, data); | |
| 13337 if (!decompressed_data) { | |
| 13338 MarkContextLost(error::kGuilty); | |
| 13339 group_->LoseContexts(error::kInnocent); | |
| 13340 return; | |
| 13341 } | |
| 13342 state_.PushTextureDecompressionUnpackState(); | |
| 13343 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, | |
| 13344 depth, format_info->decompressed_format, | |
| 13345 format_info->decompressed_type, decompressed_data.get()); | |
| 13346 state_.RestoreUnpackState(); | |
| 13347 } else { | |
| 13348 glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, | |
| 13349 height, depth, format, image_size, data); | |
| 13350 } | |
| 13351 | |
| 13352 // This may be a slow command. Exit command processing to allow for | |
| 13353 // context preemption and GPU watchdog checks. | |
| 13354 ExitCommandProcessingEarly(); | |
| 13355 } | |
| 13356 | |
| 13357 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, | 13320 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, |
| 13358 const volatile void* cmd_data) { | 13321 const volatile void* cmd_data) { |
| 13359 const char* func_name = "glTexImage2D"; | 13322 const char* func_name = "glTexImage2D"; |
| 13360 const volatile gles2::cmds::TexImage2D& c = | 13323 const volatile gles2::cmds::TexImage2D& c = |
| 13361 *static_cast<const volatile gles2::cmds::TexImage2D*>(cmd_data); | 13324 *static_cast<const volatile gles2::cmds::TexImage2D*>(cmd_data); |
| 13362 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D", | 13325 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D", |
| 13363 "width", c.width, "height", c.height); | 13326 "width", c.width, "height", c.height); |
| 13364 // Set as failed for now, but if it successed, this will be set to not failed. | 13327 // Set as failed for now, but if it successed, this will be set to not failed. |
| 13365 texture_state_.tex_image_failed = true; | 13328 texture_state_.tex_image_failed = true; |
| 13366 GLenum target = static_cast<GLenum>(c.target); | 13329 GLenum target = static_cast<GLenum>(c.target); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13533 TextureManager::DoTexImageArguments::kTexImage3D }; | 13496 TextureManager::DoTexImageArguments::kTexImage3D }; |
| 13534 texture_manager()->ValidateAndDoTexImage( | 13497 texture_manager()->ValidateAndDoTexImage( |
| 13535 &texture_state_, &state_, &framebuffer_state_, func_name, args); | 13498 &texture_state_, &state_, &framebuffer_state_, func_name, args); |
| 13536 | 13499 |
| 13537 // This may be a slow command. Exit command processing to allow for | 13500 // This may be a slow command. Exit command processing to allow for |
| 13538 // context preemption and GPU watchdog checks. | 13501 // context preemption and GPU watchdog checks. |
| 13539 ExitCommandProcessingEarly(); | 13502 ExitCommandProcessingEarly(); |
| 13540 return error::kNoError; | 13503 return error::kNoError; |
| 13541 } | 13504 } |
| 13542 | 13505 |
| 13543 void GLES2DecoderImpl::DoCompressedTexSubImage2D( | 13506 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket( |
| 13544 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 13507 uint32_t immediate_data_size, const volatile void* cmd_data) { |
| 13545 GLsizei height, GLenum format, GLsizei image_size, const void * data) { | 13508 const volatile gles2::cmds::CompressedTexSubImage2DBucket& c = |
| 13509 *static_cast<const volatile gles2::cmds::CompressedTexSubImage2DBucket*>( | |
| 13510 cmd_data); | |
| 13511 GLenum target = static_cast<GLenum>(c.target); | |
| 13512 GLint level = static_cast<GLint>(c.level); | |
| 13513 GLint xoffset = static_cast<GLint>(c.xoffset); | |
| 13514 GLint yoffset = static_cast<GLint>(c.yoffset); | |
| 13515 GLsizei width = static_cast<GLsizei>(c.width); | |
| 13516 GLsizei height = static_cast<GLsizei>(c.height); | |
| 13517 GLenum format = static_cast<GLenum>(c.format); | |
| 13518 GLuint bucket_id = static_cast<GLuint>(c.bucket_id); | |
| 13519 Bucket* bucket = GetBucket(bucket_id); | |
| 13520 if (!bucket) | |
| 13521 return error::kInvalidArguments; | |
| 13522 uint32_t image_size = bucket->size(); | |
| 13523 const void* data = bucket->GetData(0, image_size); | |
| 13524 DCHECK(data || !image_size); | |
| 13525 return DoCompressedTexSubImage(target, level, xoffset, yoffset, 0, | |
| 13526 width, height, 1, format, image_size, data, | |
| 13527 ContextState::k2D); | |
| 13528 } | |
| 13529 | |
| 13530 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2D( | |
| 13531 uint32_t immediate_data_size, | |
| 13532 const volatile void* cmd_data) { | |
| 13533 const volatile gles2::cmds::CompressedTexSubImage2D& c = | |
| 13534 *static_cast<const volatile gles2::cmds::CompressedTexSubImage2D*>( | |
| 13535 cmd_data); | |
| 13536 GLenum target = static_cast<GLenum>(c.target); | |
| 13537 GLint level = static_cast<GLint>(c.level); | |
| 13538 GLint xoffset = static_cast<GLint>(c.xoffset); | |
| 13539 GLint yoffset = static_cast<GLint>(c.yoffset); | |
| 13540 GLsizei width = static_cast<GLsizei>(c.width); | |
| 13541 GLsizei height = static_cast<GLsizei>(c.height); | |
| 13542 GLenum format = static_cast<GLenum>(c.format); | |
| 13543 GLsizei image_size = static_cast<GLsizei>(c.imageSize); | |
| 13544 uint32_t data_shm_id = c.data_shm_id; | |
| 13545 uint32_t data_shm_offset = c.data_shm_offset; | |
| 13546 | |
| 13547 const void* data; | |
| 13548 if (state_.bound_pixel_unpack_buffer.get()) { | |
| 13549 if (data_shm_id) { | |
| 13550 return error::kInvalidArguments; | |
| 13551 } | |
| 13552 data = reinterpret_cast<const void*>(data_shm_offset); | |
| 13553 } else { | |
| 13554 if (!data_shm_id && data_shm_offset) { | |
| 13555 return error::kInvalidArguments; | |
| 13556 } | |
| 13557 data = GetSharedMemoryAs<const void*>( | |
| 13558 data_shm_id, data_shm_offset, image_size); | |
| 13559 } | |
| 13560 return DoCompressedTexSubImage(target, level, xoffset, yoffset, 0, | |
| 13561 width, height, 1, format, image_size, data, | |
| 13562 ContextState::k2D); | |
| 13563 } | |
| 13564 | |
| 13565 error::Error GLES2DecoderImpl::DoCompressedTexSubImage( | |
| 13566 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, | |
| 13567 GLsizei width, GLsizei height, GLsizei depth, GLenum format, | |
| 13568 GLsizei image_size, const void * data, ContextState::Dimension dimension) { | |
| 13569 const char* func_name; | |
| 13570 if (dimension == ContextState::k2D) { | |
| 13571 func_name = "glCompressedTexSubImage2D"; | |
| 13572 if (!validators_->texture_target.IsValid(target)) { | |
| 13573 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); | |
| 13574 return error::kNoError; | |
| 13575 } | |
| 13576 } else { | |
| 13577 DCHECK_EQ(ContextState::k3D, dimension); | |
| 13578 func_name = "glCompressedTexSubImage3D"; | |
| 13579 if (!validators_->texture_3_d_target.IsValid(target)) { | |
| 13580 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); | |
| 13581 return error::kNoError; | |
| 13582 } | |
| 13583 } | |
| 13584 if (!validators_->compressed_texture_format.IsValid(format)) { | |
| 13585 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, format, "format"); | |
| 13586 return error::kNoError; | |
| 13587 } | |
| 13588 if (image_size < 0) { | |
| 13589 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "imageSize < 0"); | |
| 13590 return error::kNoError; | |
| 13591 } | |
| 13592 if (!texture_manager()->ValidForTarget(target, level, width, height, depth)) { | |
| 13593 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range"); | |
| 13594 return error::kNoError; | |
| 13595 } | |
| 13546 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( | 13596 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( |
| 13547 &state_, target); | 13597 &state_, target); |
| 13548 if (!texture_ref) { | 13598 if (!texture_ref) { |
| 13549 LOCAL_SET_GL_ERROR( | 13599 LOCAL_SET_GL_ERROR( |
| 13550 GL_INVALID_OPERATION, | 13600 GL_INVALID_OPERATION, func_name, "no texture bound at target"); |
| 13551 "glCompressedTexSubImage2D", "unknown texture for target"); | 13601 return error::kNoError; |
| 13552 return; | |
| 13553 } | |
| 13554 if (!texture_manager()->ValidForTarget(target, level, width, height, 1)) { | |
| 13555 LOCAL_SET_GL_ERROR( | |
| 13556 GL_INVALID_VALUE, | |
| 13557 "glCompressedTexSubImage2D", "dimensions out of range"); | |
| 13558 return; | |
| 13559 } | 13602 } |
| 13560 Texture* texture = texture_ref->texture(); | 13603 Texture* texture = texture_ref->texture(); |
| 13561 GLenum type = 0; | 13604 GLenum type = 0; |
| 13562 GLenum internal_format = 0; | 13605 GLenum internal_format = 0; |
| 13563 if (!texture->GetLevelType(target, level, &type, &internal_format)) { | 13606 if (!texture->GetLevelType(target, level, &type, &internal_format)) { |
| 13564 std::string msg = base::StringPrintf( | 13607 std::string msg = base::StringPrintf("level %d does not exist", level); |
| 13565 "level %d does not exist", level); | 13608 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, msg.c_str()); |
| 13566 LOCAL_SET_GL_ERROR( | 13609 return error::kNoError; |
| 13567 GL_INVALID_OPERATION, "glCompressedTexSubImage2D", msg.c_str()); | |
| 13568 return; | |
| 13569 } | 13610 } |
| 13570 if (internal_format != format) { | 13611 if (internal_format != format) { |
| 13571 LOCAL_SET_GL_ERROR( | 13612 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 13572 GL_INVALID_OPERATION, | 13613 "format does not match internalformat."); |
| 13573 "glCompressedTexSubImage2D", "format does not match internal format."); | 13614 return error::kNoError; |
| 13574 return; | |
| 13575 } | 13615 } |
| 13576 if (!texture->ValidForTexture(target, level, xoffset, yoffset, 0, width, | 13616 if (!texture->ValidForTexture(target, level, xoffset, yoffset, zoffset, |
| 13577 height, 1)) { | 13617 width, height, depth)) { |
| 13578 LOCAL_SET_GL_ERROR( | 13618 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "bad dimensions."); |
| 13579 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions."); | 13619 return error::kNoError; |
| 13580 return; | |
| 13581 } | 13620 } |
| 13582 | 13621 |
| 13583 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage2D", width, height, | 13622 if (!ValidateCompressedTexFuncData( |
| 13584 1, format, image_size, data) || | 13623 func_name, width, height, depth, format, image_size, data) || |
| 13585 !ValidateCompressedTexSubDimensions("glCompressedTexSubImage2D", target, | 13624 !ValidateCompressedTexSubDimensions( |
| 13586 level, xoffset, yoffset, 0, width, | 13625 func_name, target, level, xoffset, yoffset, zoffset, |
| 13587 height, 1, format, texture)) { | 13626 width, height, depth, format, texture)) { |
| 13588 return; | 13627 return error::kNoError; |
| 13589 } | 13628 } |
| 13590 | 13629 |
| 13591 if (!texture->IsLevelCleared(target, level)) { | 13630 // Note: There is no need to deal with texture cleared tracking here |
| 13592 // This can only happen if the compressed texture was allocated | 13631 // because the validation above means you can only get here if the level |
| 13593 // using TexStorage2D. | 13632 // is already a matching compressed format and in that case |
| 13594 DCHECK(texture->IsImmutable()); | 13633 // CompressedTexImage{2|3}D already cleared the texture. |
| 13595 GLsizei level_width = 0, level_height = 0; | 13634 DCHECK(texture->IsLevelCleared(target, level)); |
| 13596 bool success = texture->GetLevelSize( | |
| 13597 target, level, &level_width, &level_height, nullptr); | |
| 13598 DCHECK(success); | |
| 13599 // We can skip the clear if we're uploading the entire level. | |
| 13600 if (xoffset == 0 && yoffset == 0 && | |
| 13601 width == level_width && height == level_height) { | |
| 13602 texture_manager()->SetLevelCleared(texture_ref, target, level, true); | |
| 13603 } else { | |
| 13604 texture_manager()->ClearTextureLevel(this, texture_ref, target, level); | |
| 13605 } | |
| 13606 DCHECK(texture->IsLevelCleared(target, level)); | |
| 13607 } | |
| 13608 | 13635 |
| 13609 const CompressedFormatInfo* format_info = | 13636 const CompressedFormatInfo* format_info = |
| 13610 GetCompressedFormatInfo(internal_format); | 13637 GetCompressedFormatInfo(internal_format); |
| 13611 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | 13638 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { |
| 13612 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( | 13639 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( |
| 13613 state_, *format_info, width, height, 1, image_size, data); | 13640 state_, *format_info, width, height, depth, image_size, data); |
| 13614 if (!decompressed_data) { | 13641 if (!decompressed_data) { |
| 13615 MarkContextLost(error::kGuilty); | 13642 MarkContextLost(error::kGuilty); |
| 13616 group_->LoseContexts(error::kInnocent); | 13643 group_->LoseContexts(error::kInnocent); |
| 13617 return; | 13644 return error::kLostContext; |
| 13618 } | 13645 } |
| 13619 state_.PushTextureDecompressionUnpackState(); | 13646 state_.PushTextureDecompressionUnpackState(); |
| 13620 glTexSubImage2D(target, level, xoffset, yoffset, width, height, | 13647 if (dimension == ContextState::k2D) { |
| 13621 format_info->decompressed_format, | 13648 glTexSubImage2D(target, level, xoffset, yoffset, width, height, |
| 13622 format_info->decompressed_type, decompressed_data.get()); | 13649 format_info->decompressed_format, |
| 13650 format_info->decompressed_type, decompressed_data.get()); | |
| 13651 } else { | |
| 13652 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, | |
| 13653 depth, format_info->decompressed_format, | |
| 13654 format_info->decompressed_type, decompressed_data.get()); | |
| 13655 } | |
| 13623 state_.RestoreUnpackState(); | 13656 state_.RestoreUnpackState(); |
| 13624 } else { | 13657 } else { |
| 13625 glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, | 13658 if (dimension == ContextState::k2D) { |
| 13626 format, image_size, data); | 13659 glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, |
| 13660 format, image_size, data); | |
| 13661 } else { | |
| 13662 glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, | |
| 13663 height, depth, format, image_size, data); | |
| 13664 } | |
| 13627 } | 13665 } |
| 13628 | 13666 |
| 13629 // This may be a slow command. Exit command processing to allow for | 13667 // This may be a slow command. Exit command processing to allow for |
| 13630 // context preemption and GPU watchdog checks. | 13668 // context preemption and GPU watchdog checks. |
| 13631 ExitCommandProcessingEarly(); | 13669 ExitCommandProcessingEarly(); |
| 13670 return error::kNoError; | |
| 13632 } | 13671 } |
| 13633 | 13672 |
| 13634 bool GLES2DecoderImpl::ValidateCopyTexFormat( | 13673 bool GLES2DecoderImpl::ValidateCopyTexFormat( |
| 13635 const char* func_name, GLenum internal_format, | 13674 const char* func_name, GLenum internal_format, |
| 13636 GLenum read_format, GLenum read_type) { | 13675 GLenum read_format, GLenum read_type) { |
| 13637 if (read_format == 0) { | 13676 if (read_format == 0) { |
| 13638 LOCAL_SET_GL_ERROR( | 13677 LOCAL_SET_GL_ERROR( |
| 13639 GL_INVALID_OPERATION, func_name, "no valid color image"); | 13678 GL_INVALID_OPERATION, func_name, "no valid color image"); |
| 13640 return false; | 13679 return false; |
| 13641 } | 13680 } |
| (...skipping 5063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 18705 } | 18744 } |
| 18706 | 18745 |
| 18707 // Include the auto-generated part of this file. We split this because it means | 18746 // Include the auto-generated part of this file. We split this because it means |
| 18708 // we can easily edit the non-auto generated parts right here in this file | 18747 // we can easily edit the non-auto generated parts right here in this file |
| 18709 // instead of having to edit some template or the code generator. | 18748 // instead of having to edit some template or the code generator. |
| 18710 #include "base/macros.h" | 18749 #include "base/macros.h" |
| 18711 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 18750 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 18712 | 18751 |
| 18713 } // namespace gles2 | 18752 } // namespace gles2 |
| 18714 } // namespace gpu | 18753 } // namespace gpu |
| OLD | NEW |