| 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 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 // Wrapper for CompressedTexSubImage2D. | 920 // Wrapper for CompressedTexSubImage2D. |
| 921 void DoCompressedTexSubImage2D( | 921 void DoCompressedTexSubImage2D( |
| 922 GLenum target, | 922 GLenum target, |
| 923 GLint level, | 923 GLint level, |
| 924 GLint xoffset, | 924 GLint xoffset, |
| 925 GLint yoffset, | 925 GLint yoffset, |
| 926 GLsizei width, | 926 GLsizei width, |
| 927 GLsizei height, | 927 GLsizei height, |
| 928 GLenum format, | 928 GLenum format, |
| 929 GLsizei imageSize, | 929 GLsizei imageSize, |
| 930 const void * data); | 930 const void* data); |
| 931 | 931 |
| 932 // Wrapper for CompressedTexSubImage3D. | 932 // Wrapper for CompressedTexSubImage3D. |
| 933 void DoCompressedTexSubImage3D( | 933 void DoCompressedTexSubImage3D( |
| 934 GLenum target, | 934 GLenum target, |
| 935 GLint level, | 935 GLint level, |
| 936 GLint xoffset, | 936 GLint xoffset, |
| 937 GLint yoffset, | 937 GLint yoffset, |
| 938 GLint zoffset, | 938 GLint zoffset, |
| 939 GLsizei width, | 939 GLsizei width, |
| 940 GLsizei height, | 940 GLsizei height, |
| 941 GLsizei depth, | 941 GLsizei depth, |
| 942 GLenum format, | 942 GLenum format, |
| 943 GLsizei image_size, | 943 GLsizei image_size, |
| 944 const void* data); | 944 const void* data); |
| 945 | 945 |
| 946 // Validate if |format| is valid for CopyTex{Sub}Image functions. |
| 947 // If not, generate a GL error and return false. |
| 948 bool ValidateCopyTexFormat(const char* func_name, GLenum internal_format, |
| 949 GLenum read_format, GLenum read_type); |
| 950 |
| 946 // Wrapper for CopyTexImage2D. | 951 // Wrapper for CopyTexImage2D. |
| 947 void DoCopyTexImage2D( | 952 void DoCopyTexImage2D( |
| 948 GLenum target, | 953 GLenum target, |
| 949 GLint level, | 954 GLint level, |
| 950 GLenum internal_format, | 955 GLenum internal_format, |
| 951 GLint x, | 956 GLint x, |
| 952 GLint y, | 957 GLint y, |
| 953 GLsizei width, | 958 GLsizei width, |
| 954 GLsizei height, | 959 GLsizei height, |
| 955 GLint border); | 960 GLint border); |
| (...skipping 11207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12163 start = 0; | 12168 start = 0; |
| 12164 } | 12169 } |
| 12165 GLint end = start + range; | 12170 GLint end = start + range; |
| 12166 if (end > sourceRange) { | 12171 if (end > sourceRange) { |
| 12167 range -= end - sourceRange; | 12172 range -= end - sourceRange; |
| 12168 } | 12173 } |
| 12169 *out_start = start; | 12174 *out_start = start; |
| 12170 *out_range = range; | 12175 *out_range = range; |
| 12171 } | 12176 } |
| 12172 | 12177 |
| 12178 bool GLES2DecoderImpl::ValidateCopyTexFormat( |
| 12179 const char* func_name, GLenum internal_format, |
| 12180 GLenum read_format, GLenum read_type) { |
| 12181 if (read_format == 0) { |
| 12182 LOCAL_SET_GL_ERROR( |
| 12183 GL_INVALID_OPERATION, func_name, "no valid color image"); |
| 12184 return false; |
| 12185 } |
| 12186 // Check we have compatible formats. |
| 12187 uint32_t channels_exist = GLES2Util::GetChannelsForFormat(read_format); |
| 12188 uint32_t channels_needed = GLES2Util::GetChannelsForFormat(internal_format); |
| 12189 if (!channels_needed || |
| 12190 (channels_needed & channels_exist) != channels_needed) { |
| 12191 LOCAL_SET_GL_ERROR( |
| 12192 GL_INVALID_OPERATION, func_name, "incompatible format"); |
| 12193 return false; |
| 12194 } |
| 12195 if (feature_info_->IsES3Enabled()) { |
| 12196 GLint color_encoding = GetColorEncodingFromInternalFormat(read_format); |
| 12197 if (color_encoding != GetColorEncodingFromInternalFormat(internal_format) || |
| 12198 GLES2Util::IsFloatFormat(internal_format) || |
| 12199 (GLES2Util::IsSignedIntegerFormat(internal_format) != |
| 12200 GLES2Util::IsSignedIntegerFormat(read_format)) || |
| 12201 (GLES2Util::IsUnsignedIntegerFormat(internal_format) != |
| 12202 GLES2Util::IsUnsignedIntegerFormat(read_format))) { |
| 12203 LOCAL_SET_GL_ERROR( |
| 12204 GL_INVALID_OPERATION, func_name, "incompatible format"); |
| 12205 return false; |
| 12206 } |
| 12207 } |
| 12208 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { |
| 12209 LOCAL_SET_GL_ERROR( |
| 12210 GL_INVALID_OPERATION, |
| 12211 func_name, "can not be used with depth or stencil textures"); |
| 12212 return false; |
| 12213 } |
| 12214 if (feature_info_->IsES3Enabled()) { |
| 12215 if (GLES2Util::IsSizedColorFormat(internal_format)) { |
| 12216 int sr, sg, sb, sa; |
| 12217 GLES2Util::GetColorFormatComponentSizes( |
| 12218 read_format, read_type, &sr, &sg, &sb, &sa); |
| 12219 DCHECK(sr > 0 || sg > 0 || sb > 0 || sa > 0); |
| 12220 int dr, dg, db, da; |
| 12221 GLES2Util::GetColorFormatComponentSizes( |
| 12222 internal_format, 0, &dr, &dg, &db, &da); |
| 12223 DCHECK(dr > 0 || dg > 0 || db > 0 || da > 0); |
| 12224 if ((dr > 0 && sr != dr) || |
| 12225 (dg > 0 && sg != dg) || |
| 12226 (db > 0 && sb != db) || |
| 12227 (da > 0 && sa != da)) { |
| 12228 LOCAL_SET_GL_ERROR( |
| 12229 GL_INVALID_OPERATION, |
| 12230 func_name, "imcompatible color component sizes"); |
| 12231 return false; |
| 12232 } |
| 12233 } |
| 12234 } |
| 12235 return true; |
| 12236 } |
| 12237 |
| 12173 void GLES2DecoderImpl::DoCopyTexImage2D( | 12238 void GLES2DecoderImpl::DoCopyTexImage2D( |
| 12174 GLenum target, | 12239 GLenum target, |
| 12175 GLint level, | 12240 GLint level, |
| 12176 GLenum internal_format, | 12241 GLenum internal_format, |
| 12177 GLint x, | 12242 GLint x, |
| 12178 GLint y, | 12243 GLint y, |
| 12179 GLsizei width, | 12244 GLsizei width, |
| 12180 GLsizei height, | 12245 GLsizei height, |
| 12181 GLint border) { | 12246 GLint border) { |
| 12247 const char* func_name = "glCopyTexImage2D"; |
| 12182 DCHECK(!ShouldDeferReads()); | 12248 DCHECK(!ShouldDeferReads()); |
| 12183 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( | 12249 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( |
| 12184 &state_, target); | 12250 &state_, target); |
| 12185 if (!texture_ref) { | 12251 if (!texture_ref) { |
| 12186 LOCAL_SET_GL_ERROR( | 12252 LOCAL_SET_GL_ERROR( |
| 12187 GL_INVALID_OPERATION, | 12253 GL_INVALID_OPERATION, func_name, "unknown texture for target"); |
| 12188 "glCopyTexImage2D", "unknown texture for target"); | |
| 12189 return; | 12254 return; |
| 12190 } | 12255 } |
| 12191 Texture* texture = texture_ref->texture(); | 12256 Texture* texture = texture_ref->texture(); |
| 12192 if (texture->IsImmutable()) { | 12257 if (texture->IsImmutable()) { |
| 12193 LOCAL_SET_GL_ERROR( | 12258 LOCAL_SET_GL_ERROR( |
| 12194 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable"); | 12259 GL_INVALID_OPERATION, func_name, "texture is immutable"); |
| 12195 return; | 12260 return; |
| 12196 } | 12261 } |
| 12197 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || | 12262 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || |
| 12198 border != 0) { | 12263 border != 0) { |
| 12199 LOCAL_SET_GL_ERROR( | 12264 LOCAL_SET_GL_ERROR( |
| 12200 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range"); | 12265 GL_INVALID_VALUE, func_name, "dimensions out of range"); |
| 12201 return; | 12266 return; |
| 12202 } | 12267 } |
| 12203 | 12268 |
| 12204 if (!CheckBoundReadFramebufferValid("glCopyTexImage2D", | 12269 if (!CheckBoundReadFramebufferValid(func_name, |
| 12205 GL_INVALID_FRAMEBUFFER_OPERATION)) { | 12270 GL_INVALID_FRAMEBUFFER_OPERATION)) { |
| 12206 return; | 12271 return; |
| 12207 } | 12272 } |
| 12208 | 12273 |
| 12209 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); | 12274 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); |
| 12210 if (read_format == 0) { | 12275 GLenum read_type = GetBoundReadFrameBufferTextureType(); |
| 12211 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyTexImage2D", | 12276 if (!ValidateCopyTexFormat(func_name, internal_format, |
| 12212 "no valid color image"); | 12277 read_format, read_type)) { |
| 12213 return; | 12278 return; |
| 12214 } | 12279 } |
| 12215 | 12280 |
| 12216 // Check we have compatible formats. | |
| 12217 uint32_t channels_exist = GLES2Util::GetChannelsForFormat(read_format); | |
| 12218 uint32_t channels_needed = GLES2Util::GetChannelsForFormat(internal_format); | |
| 12219 | |
| 12220 if ((channels_needed & channels_exist) != channels_needed) { | |
| 12221 LOCAL_SET_GL_ERROR( | |
| 12222 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format"); | |
| 12223 return; | |
| 12224 } | |
| 12225 | |
| 12226 if (feature_info_->IsES3Enabled()) { | |
| 12227 GLint color_encoding = GetColorEncodingFromInternalFormat(read_format); | |
| 12228 if (color_encoding != GetColorEncodingFromInternalFormat(internal_format) || | |
| 12229 GLES2Util::IsFloatFormat(internal_format) || | |
| 12230 (GLES2Util::IsSignedIntegerFormat(internal_format) != | |
| 12231 GLES2Util::IsSignedIntegerFormat(read_format)) || | |
| 12232 (GLES2Util::IsUnsignedIntegerFormat(internal_format) != | |
| 12233 GLES2Util::IsUnsignedIntegerFormat(read_format))) { | |
| 12234 LOCAL_SET_GL_ERROR( | |
| 12235 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format"); | |
| 12236 return; | |
| 12237 } | |
| 12238 } | |
| 12239 | |
| 12240 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { | |
| 12241 LOCAL_SET_GL_ERROR( | |
| 12242 GL_INVALID_OPERATION, | |
| 12243 "glCopyTexImage2D", "can not be used with depth or stencil textures"); | |
| 12244 return; | |
| 12245 } | |
| 12246 | |
| 12247 uint32_t pixels_size = 0; | 12281 uint32_t pixels_size = 0; |
| 12248 GLenum format = TextureManager::ExtractFormatFromStorageFormat( | 12282 GLenum format = TextureManager::ExtractFormatFromStorageFormat( |
| 12249 internal_format); | 12283 internal_format); |
| 12250 GLenum type = TextureManager::ExtractTypeFromStorageFormat(internal_format); | 12284 GLenum type = TextureManager::ExtractTypeFromStorageFormat(internal_format); |
| 12251 // Only target image size is validated here. | 12285 // Only target image size is validated here. |
| 12252 if (!GLES2Util::ComputeImageDataSizes( | 12286 if (!GLES2Util::ComputeImageDataSizes( |
| 12253 width, height, 1, format, type, | 12287 width, height, 1, format, type, |
| 12254 state_.unpack_alignment, &pixels_size, NULL, NULL)) { | 12288 state_.unpack_alignment, &pixels_size, NULL, NULL)) { |
| 12255 LOCAL_SET_GL_ERROR( | 12289 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "dimensions too large"); |
| 12256 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large"); | |
| 12257 return; | 12290 return; |
| 12258 } | 12291 } |
| 12259 | 12292 |
| 12260 if (!EnsureGPUMemoryAvailable(pixels_size)) { | 12293 if (!EnsureGPUMemoryAvailable(pixels_size)) { |
| 12261 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory"); | 12294 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "out of memory"); |
| 12262 return; | 12295 return; |
| 12263 } | 12296 } |
| 12264 | 12297 |
| 12265 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) { | 12298 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) { |
| 12266 LOCAL_SET_GL_ERROR( | 12299 LOCAL_SET_GL_ERROR( |
| 12267 GL_INVALID_OPERATION, | 12300 GL_INVALID_OPERATION, |
| 12268 "glCopyTexImage2D", "source and destination textures are the same"); | 12301 func_name, "source and destination textures are the same"); |
| 12269 return; | 12302 return; |
| 12270 } | 12303 } |
| 12271 | 12304 |
| 12272 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D"); | 12305 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(func_name); |
| 12273 ScopedResolvedFrameBufferBinder binder(this, false, true); | 12306 ScopedResolvedFrameBufferBinder binder(this, false, true); |
| 12274 gfx::Size size = GetBoundReadFrameBufferSize(); | 12307 gfx::Size size = GetBoundReadFrameBufferSize(); |
| 12275 | 12308 |
| 12276 if (texture->IsAttachedToFramebuffer()) { | 12309 if (texture->IsAttachedToFramebuffer()) { |
| 12277 framebuffer_state_.clear_state_dirty = true; | 12310 framebuffer_state_.clear_state_dirty = true; |
| 12278 } | 12311 } |
| 12279 | 12312 |
| 12280 // Clip to size to source dimensions | 12313 // Clip to size to source dimensions |
| 12281 GLint copyX = 0; | 12314 GLint copyX = 0; |
| 12282 GLint copyY = 0; | 12315 GLint copyY = 0; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 12304 destX, destY, copyX, copyY, | 12337 destX, destY, copyX, copyY, |
| 12305 copyWidth, copyHeight); | 12338 copyWidth, copyHeight); |
| 12306 } | 12339 } |
| 12307 } else { | 12340 } else { |
| 12308 GLenum final_internal_format = | 12341 GLenum final_internal_format = |
| 12309 texture_manager()->AdjustTexInternalFormat(internal_format); | 12342 texture_manager()->AdjustTexInternalFormat(internal_format); |
| 12310 | 12343 |
| 12311 // The service id and target of the texture attached to READ_FRAMEBUFFER. | 12344 // The service id and target of the texture attached to READ_FRAMEBUFFER. |
| 12312 GLuint source_texture_service_id = 0; | 12345 GLuint source_texture_service_id = 0; |
| 12313 GLenum source_texture_target = 0; | 12346 GLenum source_texture_target = 0; |
| 12347 uint32_t channels_exist = GLES2Util::GetChannelsForFormat(read_format); |
| 12314 bool use_workaround = NeedsCopyTextureImageWorkaround( | 12348 bool use_workaround = NeedsCopyTextureImageWorkaround( |
| 12315 final_internal_format, channels_exist, &source_texture_service_id, | 12349 final_internal_format, channels_exist, &source_texture_service_id, |
| 12316 &source_texture_target); | 12350 &source_texture_target); |
| 12317 if (use_workaround) { | 12351 if (use_workaround) { |
| 12318 GLenum dest_texture_target = target; | 12352 GLenum dest_texture_target = target; |
| 12319 GLenum framebuffer_target = features().chromium_framebuffer_multisample | 12353 GLenum framebuffer_target = features().chromium_framebuffer_multisample |
| 12320 ? GL_READ_FRAMEBUFFER_EXT | 12354 ? GL_READ_FRAMEBUFFER_EXT |
| 12321 : GL_FRAMEBUFFER; | 12355 : GL_FRAMEBUFFER; |
| 12322 | 12356 |
| 12323 GLenum temp_internal_format = 0; | 12357 GLenum temp_internal_format = 0; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 12352 glFramebufferTexture2DEXT(framebuffer_target, GL_COLOR_ATTACHMENT0, | 12386 glFramebufferTexture2DEXT(framebuffer_target, GL_COLOR_ATTACHMENT0, |
| 12353 source_texture_target, | 12387 source_texture_target, |
| 12354 source_texture_service_id, 0); | 12388 source_texture_service_id, 0); |
| 12355 | 12389 |
| 12356 glDeleteTextures(1, &temp_texture); | 12390 glDeleteTextures(1, &temp_texture); |
| 12357 } else { | 12391 } else { |
| 12358 glCopyTexImage2D(target, level, final_internal_format, copyX, copyY, | 12392 glCopyTexImage2D(target, level, final_internal_format, copyX, copyY, |
| 12359 copyWidth, copyHeight, border); | 12393 copyWidth, copyHeight, border); |
| 12360 } | 12394 } |
| 12361 } | 12395 } |
| 12362 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D"); | 12396 GLenum error = LOCAL_PEEK_GL_ERROR(func_name); |
| 12363 if (error == GL_NO_ERROR) { | 12397 if (error == GL_NO_ERROR) { |
| 12364 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, | 12398 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, |
| 12365 width, height, 1, border, format, | 12399 width, height, 1, border, format, |
| 12366 type, gfx::Rect(width, height)); | 12400 type, gfx::Rect(width, height)); |
| 12367 texture->ApplyFormatWorkarounds(feature_info_.get()); | 12401 texture->ApplyFormatWorkarounds(feature_info_.get()); |
| 12368 } | 12402 } |
| 12369 | 12403 |
| 12370 // This may be a slow command. Exit command processing to allow for | 12404 // This may be a slow command. Exit command processing to allow for |
| 12371 // context preemption and GPU watchdog checks. | 12405 // context preemption and GPU watchdog checks. |
| 12372 ExitCommandProcessingEarly(); | 12406 ExitCommandProcessingEarly(); |
| 12373 } | 12407 } |
| 12374 | 12408 |
| 12375 void GLES2DecoderImpl::DoCopyTexSubImage2D( | 12409 void GLES2DecoderImpl::DoCopyTexSubImage2D( |
| 12376 GLenum target, | 12410 GLenum target, |
| 12377 GLint level, | 12411 GLint level, |
| 12378 GLint xoffset, | 12412 GLint xoffset, |
| 12379 GLint yoffset, | 12413 GLint yoffset, |
| 12380 GLint x, | 12414 GLint x, |
| 12381 GLint y, | 12415 GLint y, |
| 12382 GLsizei width, | 12416 GLsizei width, |
| 12383 GLsizei height) { | 12417 GLsizei height) { |
| 12418 const char* func_name = "glCopyTexSubImage2D"; |
| 12384 DCHECK(!ShouldDeferReads()); | 12419 DCHECK(!ShouldDeferReads()); |
| 12385 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( | 12420 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( |
| 12386 &state_, target); | 12421 &state_, target); |
| 12387 if (!texture_ref) { | 12422 if (!texture_ref) { |
| 12388 LOCAL_SET_GL_ERROR( | 12423 LOCAL_SET_GL_ERROR( |
| 12389 GL_INVALID_OPERATION, | 12424 GL_INVALID_OPERATION, func_name, "unknown texture for target"); |
| 12390 "glCopyTexSubImage2D", "unknown texture for target"); | |
| 12391 return; | 12425 return; |
| 12392 } | 12426 } |
| 12393 Texture* texture = texture_ref->texture(); | 12427 Texture* texture = texture_ref->texture(); |
| 12394 GLenum type = 0; | 12428 GLenum type = 0; |
| 12395 GLenum format = 0; | 12429 GLenum internal_format = 0; |
| 12396 if (!texture->GetLevelType(target, level, &type, &format) || | 12430 if (!texture->GetLevelType(target, level, &type, &internal_format) || |
| 12397 !texture->ValidForTexture( | 12431 !texture->ValidForTexture( |
| 12398 target, level, xoffset, yoffset, 0, width, height, 1)) { | 12432 target, level, xoffset, yoffset, 0, width, height, 1)) { |
| 12399 LOCAL_SET_GL_ERROR( | 12433 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "bad dimensions."); |
| 12400 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions."); | |
| 12401 return; | 12434 return; |
| 12402 } | 12435 } |
| 12403 | 12436 |
| 12404 if (!CheckBoundReadFramebufferValid("glCopyTexImage2D", | 12437 if (!CheckBoundReadFramebufferValid(func_name, |
| 12405 GL_INVALID_FRAMEBUFFER_OPERATION)) { | 12438 GL_INVALID_FRAMEBUFFER_OPERATION)) { |
| 12406 return; | 12439 return; |
| 12407 } | 12440 } |
| 12408 | 12441 |
| 12409 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); | 12442 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); |
| 12410 if (read_format == 0) { | 12443 GLenum read_type = GetBoundReadFrameBufferTextureType(); |
| 12411 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyTexImage2D", | 12444 if (!ValidateCopyTexFormat(func_name, internal_format, |
| 12412 "no valid color image"); | 12445 read_format, read_type)) { |
| 12413 return; | |
| 12414 } | |
| 12415 // Check we have compatible formats. | |
| 12416 uint32_t channels_exist = GLES2Util::GetChannelsForFormat(read_format); | |
| 12417 uint32_t channels_needed = GLES2Util::GetChannelsForFormat(format); | |
| 12418 | |
| 12419 if (!channels_needed || | |
| 12420 (channels_needed & channels_exist) != channels_needed) { | |
| 12421 LOCAL_SET_GL_ERROR( | |
| 12422 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format"); | |
| 12423 return; | |
| 12424 } | |
| 12425 | |
| 12426 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { | |
| 12427 LOCAL_SET_GL_ERROR( | |
| 12428 GL_INVALID_OPERATION, | |
| 12429 "glCopySubImage2D", "can not be used with depth or stencil textures"); | |
| 12430 return; | 12446 return; |
| 12431 } | 12447 } |
| 12432 | 12448 |
| 12433 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) { | 12449 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) { |
| 12434 LOCAL_SET_GL_ERROR( | 12450 LOCAL_SET_GL_ERROR( |
| 12435 GL_INVALID_OPERATION, | 12451 GL_INVALID_OPERATION, |
| 12436 "glCopyTexSubImage2D", "source and destination textures are the same"); | 12452 func_name, "source and destination textures are the same"); |
| 12437 return; | 12453 return; |
| 12438 } | 12454 } |
| 12439 | 12455 |
| 12440 ScopedResolvedFrameBufferBinder binder(this, false, true); | 12456 ScopedResolvedFrameBufferBinder binder(this, false, true); |
| 12441 gfx::Size size = GetBoundReadFrameBufferSize(); | 12457 gfx::Size size = GetBoundReadFrameBufferSize(); |
| 12442 GLint copyX = 0; | 12458 GLint copyX = 0; |
| 12443 GLint copyY = 0; | 12459 GLint copyY = 0; |
| 12444 GLint copyWidth = 0; | 12460 GLint copyWidth = 0; |
| 12445 GLint copyHeight = 0; | 12461 GLint copyHeight = 0; |
| 12446 Clip(x, width, size.width(), ©X, ©Width); | 12462 Clip(x, width, size.width(), ©X, ©Width); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 12457 texture->GetLevelClearedRect(target, level), | 12473 texture->GetLevelClearedRect(target, level), |
| 12458 gfx::Rect(destX, destY, copyWidth, copyHeight), &cleared_rect)) { | 12474 gfx::Rect(destX, destY, copyWidth, copyHeight), &cleared_rect)) { |
| 12459 DCHECK_GE(cleared_rect.size().GetArea(), | 12475 DCHECK_GE(cleared_rect.size().GetArea(), |
| 12460 texture->GetLevelClearedRect(target, level).size().GetArea()); | 12476 texture->GetLevelClearedRect(target, level).size().GetArea()); |
| 12461 texture_manager()->SetLevelClearedRect(texture_ref, target, level, | 12477 texture_manager()->SetLevelClearedRect(texture_ref, target, level, |
| 12462 cleared_rect); | 12478 cleared_rect); |
| 12463 } else { | 12479 } else { |
| 12464 // Otherwise clear part of texture level that is not already cleared. | 12480 // Otherwise clear part of texture level that is not already cleared. |
| 12465 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, | 12481 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, |
| 12466 level)) { | 12482 level)) { |
| 12467 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", | 12483 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "dimensions too big"); |
| 12468 "dimensions too big"); | |
| 12469 return; | 12484 return; |
| 12470 } | 12485 } |
| 12471 } | 12486 } |
| 12472 } else { | 12487 } else { |
| 12473 // Write all pixels in below. | 12488 // Write all pixels in below. |
| 12474 texture_manager()->SetLevelCleared(texture_ref, target, level, true); | 12489 texture_manager()->SetLevelCleared(texture_ref, target, level, true); |
| 12475 } | 12490 } |
| 12476 | 12491 |
| 12477 if (copyHeight > 0 && copyWidth > 0) { | 12492 if (copyHeight > 0 && copyWidth > 0) { |
| 12478 glCopyTexSubImage2D(target, level, | 12493 glCopyTexSubImage2D(target, level, |
| (...skipping 4437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16916 } | 16931 } |
| 16917 | 16932 |
| 16918 // Include the auto-generated part of this file. We split this because it means | 16933 // Include the auto-generated part of this file. We split this because it means |
| 16919 // we can easily edit the non-auto generated parts right here in this file | 16934 // we can easily edit the non-auto generated parts right here in this file |
| 16920 // instead of having to edit some template or the code generator. | 16935 // instead of having to edit some template or the code generator. |
| 16921 #include "base/macros.h" | 16936 #include "base/macros.h" |
| 16922 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 16937 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 16923 | 16938 |
| 16924 } // namespace gles2 | 16939 } // namespace gles2 |
| 16925 } // namespace gpu | 16940 } // namespace gpu |
| OLD | NEW |