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