Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
index 3553a7addd858e7cb242b33d42bf54ab83c16e32..fd925b1eda8842890a3da1cd3bda38604504d2a2 100644 |
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
@@ -7920,15 +7920,17 @@ const int kS3TCBlockWidth = 4; |
const int kS3TCBlockHeight = 4; |
const int kS3TCDXT1BlockSize = 8; |
const int kS3TCDXT3AndDXT5BlockSize = 16; |
-const int kETC1BlockWidth = 4; |
-const int kETC1BlockHeight = 4; |
-const int kETC1BlockSize = 8; |
bool IsValidDXTSize(GLint level, GLsizei size) { |
return (size == 1) || |
(size == 2) || !(size % kS3TCBlockWidth); |
} |
+bool IsValidPVRTCSize(GLint level, GLsizei size) { |
+ // Ensure that the size is a power of two |
+ return (size & (size - 1)) == 0; |
+} |
+ |
} // anonymous namespace. |
bool GLES2DecoderImpl::ValidateCompressedTexFuncData( |
@@ -7937,8 +7939,10 @@ bool GLES2DecoderImpl::ValidateCompressedTexFuncData( |
unsigned int bytes_required = 0; |
switch (format) { |
+ case GL_ATC_RGB_AMD: |
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: |
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: { |
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: |
+ case GL_ETC1_RGB8_OES: { |
int num_blocks_across = |
(width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; |
int num_blocks_down = |
@@ -7947,6 +7951,8 @@ bool GLES2DecoderImpl::ValidateCompressedTexFuncData( |
bytes_required = num_blocks * kS3TCDXT1BlockSize; |
break; |
} |
+ case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: |
+ case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: |
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: |
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { |
int num_blocks_across = |
@@ -7957,13 +7963,14 @@ bool GLES2DecoderImpl::ValidateCompressedTexFuncData( |
bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize; |
break; |
} |
- case GL_ETC1_RGB8_OES: { |
- int num_blocks_across = |
- (width + kETC1BlockWidth - 1) / kETC1BlockWidth; |
- int num_blocks_down = |
- (height + kETC1BlockHeight - 1) / kETC1BlockHeight; |
- int num_blocks = num_blocks_across * num_blocks_down; |
- bytes_required = num_blocks * kETC1BlockSize; |
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: |
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: { |
+ bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8; |
+ break; |
+ } |
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: |
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { |
+ bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8; |
break; |
} |
default: |
@@ -7996,7 +8003,10 @@ bool GLES2DecoderImpl::ValidateCompressedTexDimensions( |
} |
return true; |
} |
- case GL_ETC1_RGB8_OES: |
+ case GL_ATC_RGB_AMD: |
+ case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: |
+ case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: |
+ case GL_ETC1_RGB8_OES: { |
if (width <= 0 || height <= 0) { |
LOCAL_SET_GL_ERROR( |
GL_INVALID_OPERATION, function_name, |
@@ -8004,6 +8014,20 @@ bool GLES2DecoderImpl::ValidateCompressedTexDimensions( |
return false; |
} |
return true; |
+ } |
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: |
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: |
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: |
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { |
+ if (!IsValidPVRTCSize(level, width) || |
+ !IsValidPVRTCSize(level, height)) { |
+ LOCAL_SET_GL_ERROR( |
+ GL_INVALID_OPERATION, function_name, |
+ "width or height invalid for level"); |
+ return false; |
+ } |
+ return true; |
+ } |
default: |
return false; |
} |
@@ -8045,12 +8069,43 @@ bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( |
return ValidateCompressedTexDimensions( |
function_name, level, width, height, format); |
} |
+ case GL_ATC_RGB_AMD: |
+ case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: |
+ case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: { |
+ LOCAL_SET_GL_ERROR( |
+ GL_INVALID_OPERATION, function_name, |
+ "not supported for ATC textures"); |
+ return false; |
+ } |
case GL_ETC1_RGB8_OES: { |
LOCAL_SET_GL_ERROR( |
GL_INVALID_OPERATION, function_name, |
"not supported for ECT1_RGB8_OES textures"); |
return false; |
} |
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: |
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: |
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: |
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { |
+ if ((xoffset != 0) || (yoffset != 0)) { |
+ LOCAL_SET_GL_ERROR( |
+ GL_INVALID_OPERATION, function_name, |
+ "xoffset and yoffset must be zero"); |
+ return false; |
+ } |
+ GLsizei tex_width = 0; |
+ GLsizei tex_height = 0; |
+ if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || |
+ width != tex_width || |
+ height != tex_height) { |
+ LOCAL_SET_GL_ERROR( |
+ GL_INVALID_OPERATION, function_name, |
+ "dimensions must match existing texture level dimensions"); |
+ return false; |
+ } |
+ return ValidateCompressedTexDimensions( |
+ function_name, level, width, height, format); |
+ } |
default: |
return false; |
} |