OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <list> | 10 #include <list> |
(...skipping 7888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7899 glBindTexture(bind_target, texture ? texture->service_id() : 0); | 7899 glBindTexture(bind_target, texture ? texture->service_id() : 0); |
7900 return true; | 7900 return true; |
7901 } | 7901 } |
7902 | 7902 |
7903 namespace { | 7903 namespace { |
7904 | 7904 |
7905 const int kS3TCBlockWidth = 4; | 7905 const int kS3TCBlockWidth = 4; |
7906 const int kS3TCBlockHeight = 4; | 7906 const int kS3TCBlockHeight = 4; |
7907 const int kS3TCDXT1BlockSize = 8; | 7907 const int kS3TCDXT1BlockSize = 8; |
7908 const int kS3TCDXT3AndDXT5BlockSize = 16; | 7908 const int kS3TCDXT3AndDXT5BlockSize = 16; |
7909 const int kETC1BlockWidth = 4; | |
7910 const int kETC1BlockHeight = 4; | |
7911 const int kETC1BlockSize = 8; | |
7912 | 7909 |
7913 bool IsValidDXTSize(GLint level, GLsizei size) { | 7910 bool IsValidDXTSize(GLint level, GLsizei size) { |
7914 return (size == 1) || | 7911 return (size == 1) || |
7915 (size == 2) || !(size % kS3TCBlockWidth); | 7912 (size == 2) || !(size % kS3TCBlockWidth); |
7916 } | 7913 } |
7917 | 7914 |
| 7915 bool IsValidPVRTCSize(GLint level, GLsizei size) { |
| 7916 // Ensure that the size is a power of two |
| 7917 return (size & (size - 1)) == 0; |
| 7918 } |
| 7919 |
7918 } // anonymous namespace. | 7920 } // anonymous namespace. |
7919 | 7921 |
7920 bool GLES2DecoderImpl::ValidateCompressedTexFuncData( | 7922 bool GLES2DecoderImpl::ValidateCompressedTexFuncData( |
7921 const char* function_name, | 7923 const char* function_name, |
7922 GLsizei width, GLsizei height, GLenum format, size_t size) { | 7924 GLsizei width, GLsizei height, GLenum format, size_t size) { |
7923 unsigned int bytes_required = 0; | 7925 unsigned int bytes_required = 0; |
7924 | 7926 |
7925 switch (format) { | 7927 switch (format) { |
| 7928 case GL_ATC_RGB_AMD: |
7926 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: | 7929 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: |
7927 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: { | 7930 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: |
| 7931 case GL_ETC1_RGB8_OES: { |
7928 int num_blocks_across = | 7932 int num_blocks_across = |
7929 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; | 7933 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; |
7930 int num_blocks_down = | 7934 int num_blocks_down = |
7931 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; | 7935 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; |
7932 int num_blocks = num_blocks_across * num_blocks_down; | 7936 int num_blocks = num_blocks_across * num_blocks_down; |
7933 bytes_required = num_blocks * kS3TCDXT1BlockSize; | 7937 bytes_required = num_blocks * kS3TCDXT1BlockSize; |
7934 break; | 7938 break; |
7935 } | 7939 } |
| 7940 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: |
| 7941 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: |
7936 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: | 7942 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: |
7937 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { | 7943 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { |
7938 int num_blocks_across = | 7944 int num_blocks_across = |
7939 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; | 7945 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; |
7940 int num_blocks_down = | 7946 int num_blocks_down = |
7941 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; | 7947 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; |
7942 int num_blocks = num_blocks_across * num_blocks_down; | 7948 int num_blocks = num_blocks_across * num_blocks_down; |
7943 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize; | 7949 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize; |
7944 break; | 7950 break; |
7945 } | 7951 } |
7946 case GL_ETC1_RGB8_OES: { | 7952 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: |
7947 int num_blocks_across = | 7953 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: { |
7948 (width + kETC1BlockWidth - 1) / kETC1BlockWidth; | 7954 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8; |
7949 int num_blocks_down = | 7955 break; |
7950 (height + kETC1BlockHeight - 1) / kETC1BlockHeight; | 7956 } |
7951 int num_blocks = num_blocks_across * num_blocks_down; | 7957 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: |
7952 bytes_required = num_blocks * kETC1BlockSize; | 7958 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { |
| 7959 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8; |
7953 break; | 7960 break; |
7954 } | 7961 } |
7955 default: | 7962 default: |
7956 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format"); | 7963 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format"); |
7957 return false; | 7964 return false; |
7958 } | 7965 } |
7959 | 7966 |
7960 if (size != bytes_required) { | 7967 if (size != bytes_required) { |
7961 LOCAL_SET_GL_ERROR( | 7968 LOCAL_SET_GL_ERROR( |
7962 GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); | 7969 GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); |
(...skipping 12 matching lines...) Expand all Loading... |
7975 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: | 7982 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: |
7976 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { | 7983 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { |
7977 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) { | 7984 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) { |
7978 LOCAL_SET_GL_ERROR( | 7985 LOCAL_SET_GL_ERROR( |
7979 GL_INVALID_OPERATION, function_name, | 7986 GL_INVALID_OPERATION, function_name, |
7980 "width or height invalid for level"); | 7987 "width or height invalid for level"); |
7981 return false; | 7988 return false; |
7982 } | 7989 } |
7983 return true; | 7990 return true; |
7984 } | 7991 } |
7985 case GL_ETC1_RGB8_OES: | 7992 case GL_ATC_RGB_AMD: |
| 7993 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: |
| 7994 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: |
| 7995 case GL_ETC1_RGB8_OES: { |
7986 if (width <= 0 || height <= 0) { | 7996 if (width <= 0 || height <= 0) { |
7987 LOCAL_SET_GL_ERROR( | 7997 LOCAL_SET_GL_ERROR( |
7988 GL_INVALID_OPERATION, function_name, | 7998 GL_INVALID_OPERATION, function_name, |
7989 "width or height invalid for level"); | 7999 "width or height invalid for level"); |
7990 return false; | 8000 return false; |
7991 } | 8001 } |
7992 return true; | 8002 return true; |
| 8003 } |
| 8004 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: |
| 8005 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: |
| 8006 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: |
| 8007 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { |
| 8008 if (!IsValidPVRTCSize(level, width) || |
| 8009 !IsValidPVRTCSize(level, height)) { |
| 8010 LOCAL_SET_GL_ERROR( |
| 8011 GL_INVALID_OPERATION, function_name, |
| 8012 "width or height invalid for level"); |
| 8013 return false; |
| 8014 } |
| 8015 return true; |
| 8016 } |
7993 default: | 8017 default: |
7994 return false; | 8018 return false; |
7995 } | 8019 } |
7996 } | 8020 } |
7997 | 8021 |
7998 bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( | 8022 bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( |
7999 const char* function_name, | 8023 const char* function_name, |
8000 GLenum target, GLint level, GLint xoffset, GLint yoffset, | 8024 GLenum target, GLint level, GLint xoffset, GLint yoffset, |
8001 GLsizei width, GLsizei height, GLenum format, | 8025 GLsizei width, GLsizei height, GLenum format, |
8002 Texture* texture) { | 8026 Texture* texture) { |
(...skipping 21 matching lines...) Expand all Loading... |
8024 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || | 8048 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || |
8025 width - xoffset > tex_width || | 8049 width - xoffset > tex_width || |
8026 height - yoffset > tex_height) { | 8050 height - yoffset > tex_height) { |
8027 LOCAL_SET_GL_ERROR( | 8051 LOCAL_SET_GL_ERROR( |
8028 GL_INVALID_OPERATION, function_name, "dimensions out of range"); | 8052 GL_INVALID_OPERATION, function_name, "dimensions out of range"); |
8029 return false; | 8053 return false; |
8030 } | 8054 } |
8031 return ValidateCompressedTexDimensions( | 8055 return ValidateCompressedTexDimensions( |
8032 function_name, level, width, height, format); | 8056 function_name, level, width, height, format); |
8033 } | 8057 } |
| 8058 case GL_ATC_RGB_AMD: |
| 8059 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: |
| 8060 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: { |
| 8061 LOCAL_SET_GL_ERROR( |
| 8062 GL_INVALID_OPERATION, function_name, |
| 8063 "not supported for ATC textures"); |
| 8064 return false; |
| 8065 } |
8034 case GL_ETC1_RGB8_OES: { | 8066 case GL_ETC1_RGB8_OES: { |
8035 LOCAL_SET_GL_ERROR( | 8067 LOCAL_SET_GL_ERROR( |
8036 GL_INVALID_OPERATION, function_name, | 8068 GL_INVALID_OPERATION, function_name, |
8037 "not supported for ECT1_RGB8_OES textures"); | 8069 "not supported for ECT1_RGB8_OES textures"); |
8038 return false; | 8070 return false; |
8039 } | 8071 } |
| 8072 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: |
| 8073 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: |
| 8074 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: |
| 8075 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { |
| 8076 if ((xoffset != 0) || (yoffset != 0)) { |
| 8077 LOCAL_SET_GL_ERROR( |
| 8078 GL_INVALID_OPERATION, function_name, |
| 8079 "xoffset and yoffset must be zero"); |
| 8080 return false; |
| 8081 } |
| 8082 GLsizei tex_width = 0; |
| 8083 GLsizei tex_height = 0; |
| 8084 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || |
| 8085 width != tex_width || |
| 8086 height != tex_height) { |
| 8087 LOCAL_SET_GL_ERROR( |
| 8088 GL_INVALID_OPERATION, function_name, |
| 8089 "dimensions must match existing texture level dimensions"); |
| 8090 return false; |
| 8091 } |
| 8092 return ValidateCompressedTexDimensions( |
| 8093 function_name, level, width, height, format); |
| 8094 } |
8040 default: | 8095 default: |
8041 return false; | 8096 return false; |
8042 } | 8097 } |
8043 } | 8098 } |
8044 | 8099 |
8045 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( | 8100 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( |
8046 GLenum target, | 8101 GLenum target, |
8047 GLint level, | 8102 GLint level, |
8048 GLenum internal_format, | 8103 GLenum internal_format, |
8049 GLsizei width, | 8104 GLsizei width, |
(...skipping 2692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10742 } | 10797 } |
10743 } | 10798 } |
10744 | 10799 |
10745 // Include the auto-generated part of this file. We split this because it means | 10800 // Include the auto-generated part of this file. We split this because it means |
10746 // we can easily edit the non-auto generated parts right here in this file | 10801 // we can easily edit the non-auto generated parts right here in this file |
10747 // instead of having to edit some template or the code generator. | 10802 // instead of having to edit some template or the code generator. |
10748 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 10803 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
10749 | 10804 |
10750 } // namespace gles2 | 10805 } // namespace gles2 |
10751 } // namespace gpu | 10806 } // namespace gpu |
OLD | NEW |