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 7902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7913 glBindTexture(bind_target, texture ? texture->service_id() : 0); | 7913 glBindTexture(bind_target, texture ? texture->service_id() : 0); |
7914 return true; | 7914 return true; |
7915 } | 7915 } |
7916 | 7916 |
7917 namespace { | 7917 namespace { |
7918 | 7918 |
7919 const int kS3TCBlockWidth = 4; | 7919 const int kS3TCBlockWidth = 4; |
7920 const int kS3TCBlockHeight = 4; | 7920 const int kS3TCBlockHeight = 4; |
7921 const int kS3TCDXT1BlockSize = 8; | 7921 const int kS3TCDXT1BlockSize = 8; |
7922 const int kS3TCDXT3AndDXT5BlockSize = 16; | 7922 const int kS3TCDXT3AndDXT5BlockSize = 16; |
7923 const int kETC1BlockWidth = 4; | |
7924 const int kETC1BlockHeight = 4; | |
7925 const int kETC1BlockSize = 8; | |
7926 | 7923 |
7927 bool IsValidDXTSize(GLint level, GLsizei size) { | 7924 bool IsValidDXTSize(GLint level, GLsizei size) { |
7928 return (size == 1) || | 7925 return (size == 1) || |
7929 (size == 2) || !(size % kS3TCBlockWidth); | 7926 (size == 2) || !(size % kS3TCBlockWidth); |
7930 } | 7927 } |
7931 | 7928 |
| 7929 bool IsValidPVRTCSize(GLint level, GLsizei size) { |
| 7930 // Ensure that the size is a power of two |
| 7931 return (size & (size - 1)) == 0; |
| 7932 } |
| 7933 |
7932 } // anonymous namespace. | 7934 } // anonymous namespace. |
7933 | 7935 |
7934 bool GLES2DecoderImpl::ValidateCompressedTexFuncData( | 7936 bool GLES2DecoderImpl::ValidateCompressedTexFuncData( |
7935 const char* function_name, | 7937 const char* function_name, |
7936 GLsizei width, GLsizei height, GLenum format, size_t size) { | 7938 GLsizei width, GLsizei height, GLenum format, size_t size) { |
7937 unsigned int bytes_required = 0; | 7939 unsigned int bytes_required = 0; |
7938 | 7940 |
7939 switch (format) { | 7941 switch (format) { |
| 7942 case GL_ATC_RGB_AMD: |
7940 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: | 7943 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: |
7941 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: { | 7944 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: |
| 7945 case GL_ETC1_RGB8_OES: { |
7942 int num_blocks_across = | 7946 int num_blocks_across = |
7943 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; | 7947 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; |
7944 int num_blocks_down = | 7948 int num_blocks_down = |
7945 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; | 7949 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; |
7946 int num_blocks = num_blocks_across * num_blocks_down; | 7950 int num_blocks = num_blocks_across * num_blocks_down; |
7947 bytes_required = num_blocks * kS3TCDXT1BlockSize; | 7951 bytes_required = num_blocks * kS3TCDXT1BlockSize; |
7948 break; | 7952 break; |
7949 } | 7953 } |
| 7954 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: |
| 7955 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: |
7950 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: | 7956 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: |
7951 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { | 7957 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { |
7952 int num_blocks_across = | 7958 int num_blocks_across = |
7953 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; | 7959 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; |
7954 int num_blocks_down = | 7960 int num_blocks_down = |
7955 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; | 7961 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; |
7956 int num_blocks = num_blocks_across * num_blocks_down; | 7962 int num_blocks = num_blocks_across * num_blocks_down; |
7957 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize; | 7963 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize; |
7958 break; | 7964 break; |
7959 } | 7965 } |
7960 case GL_ETC1_RGB8_OES: { | 7966 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: |
7961 int num_blocks_across = | 7967 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: { |
7962 (width + kETC1BlockWidth - 1) / kETC1BlockWidth; | 7968 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8; |
7963 int num_blocks_down = | 7969 break; |
7964 (height + kETC1BlockHeight - 1) / kETC1BlockHeight; | 7970 } |
7965 int num_blocks = num_blocks_across * num_blocks_down; | 7971 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: |
7966 bytes_required = num_blocks * kETC1BlockSize; | 7972 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { |
| 7973 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8; |
7967 break; | 7974 break; |
7968 } | 7975 } |
7969 default: | 7976 default: |
7970 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format"); | 7977 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format"); |
7971 return false; | 7978 return false; |
7972 } | 7979 } |
7973 | 7980 |
7974 if (size != bytes_required) { | 7981 if (size != bytes_required) { |
7975 LOCAL_SET_GL_ERROR( | 7982 LOCAL_SET_GL_ERROR( |
7976 GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); | 7983 GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); |
(...skipping 12 matching lines...) Expand all Loading... |
7989 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: | 7996 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: |
7990 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { | 7997 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { |
7991 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) { | 7998 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) { |
7992 LOCAL_SET_GL_ERROR( | 7999 LOCAL_SET_GL_ERROR( |
7993 GL_INVALID_OPERATION, function_name, | 8000 GL_INVALID_OPERATION, function_name, |
7994 "width or height invalid for level"); | 8001 "width or height invalid for level"); |
7995 return false; | 8002 return false; |
7996 } | 8003 } |
7997 return true; | 8004 return true; |
7998 } | 8005 } |
7999 case GL_ETC1_RGB8_OES: | 8006 case GL_ATC_RGB_AMD: |
| 8007 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: |
| 8008 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: |
| 8009 case GL_ETC1_RGB8_OES: { |
8000 if (width <= 0 || height <= 0) { | 8010 if (width <= 0 || height <= 0) { |
8001 LOCAL_SET_GL_ERROR( | 8011 LOCAL_SET_GL_ERROR( |
8002 GL_INVALID_OPERATION, function_name, | 8012 GL_INVALID_OPERATION, function_name, |
8003 "width or height invalid for level"); | 8013 "width or height invalid for level"); |
8004 return false; | 8014 return false; |
8005 } | 8015 } |
8006 return true; | 8016 return true; |
| 8017 } |
| 8018 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: |
| 8019 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: |
| 8020 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: |
| 8021 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { |
| 8022 if (!IsValidPVRTCSize(level, width) || |
| 8023 !IsValidPVRTCSize(level, height)) { |
| 8024 LOCAL_SET_GL_ERROR( |
| 8025 GL_INVALID_OPERATION, function_name, |
| 8026 "width or height invalid for level"); |
| 8027 return false; |
| 8028 } |
| 8029 return true; |
| 8030 } |
8007 default: | 8031 default: |
8008 return false; | 8032 return false; |
8009 } | 8033 } |
8010 } | 8034 } |
8011 | 8035 |
8012 bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( | 8036 bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( |
8013 const char* function_name, | 8037 const char* function_name, |
8014 GLenum target, GLint level, GLint xoffset, GLint yoffset, | 8038 GLenum target, GLint level, GLint xoffset, GLint yoffset, |
8015 GLsizei width, GLsizei height, GLenum format, | 8039 GLsizei width, GLsizei height, GLenum format, |
8016 Texture* texture) { | 8040 Texture* texture) { |
(...skipping 21 matching lines...) Expand all Loading... |
8038 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || | 8062 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || |
8039 width - xoffset > tex_width || | 8063 width - xoffset > tex_width || |
8040 height - yoffset > tex_height) { | 8064 height - yoffset > tex_height) { |
8041 LOCAL_SET_GL_ERROR( | 8065 LOCAL_SET_GL_ERROR( |
8042 GL_INVALID_OPERATION, function_name, "dimensions out of range"); | 8066 GL_INVALID_OPERATION, function_name, "dimensions out of range"); |
8043 return false; | 8067 return false; |
8044 } | 8068 } |
8045 return ValidateCompressedTexDimensions( | 8069 return ValidateCompressedTexDimensions( |
8046 function_name, level, width, height, format); | 8070 function_name, level, width, height, format); |
8047 } | 8071 } |
| 8072 case GL_ATC_RGB_AMD: |
| 8073 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: |
| 8074 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: { |
| 8075 LOCAL_SET_GL_ERROR( |
| 8076 GL_INVALID_OPERATION, function_name, |
| 8077 "not supported for ATC textures"); |
| 8078 return false; |
| 8079 } |
8048 case GL_ETC1_RGB8_OES: { | 8080 case GL_ETC1_RGB8_OES: { |
8049 LOCAL_SET_GL_ERROR( | 8081 LOCAL_SET_GL_ERROR( |
8050 GL_INVALID_OPERATION, function_name, | 8082 GL_INVALID_OPERATION, function_name, |
8051 "not supported for ECT1_RGB8_OES textures"); | 8083 "not supported for ECT1_RGB8_OES textures"); |
8052 return false; | 8084 return false; |
8053 } | 8085 } |
| 8086 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: |
| 8087 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: |
| 8088 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: |
| 8089 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { |
| 8090 if ((xoffset != 0) || (yoffset != 0)) { |
| 8091 LOCAL_SET_GL_ERROR( |
| 8092 GL_INVALID_OPERATION, function_name, |
| 8093 "xoffset and yoffset must be zero"); |
| 8094 return false; |
| 8095 } |
| 8096 GLsizei tex_width = 0; |
| 8097 GLsizei tex_height = 0; |
| 8098 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || |
| 8099 width != tex_width || |
| 8100 height != tex_height) { |
| 8101 LOCAL_SET_GL_ERROR( |
| 8102 GL_INVALID_OPERATION, function_name, |
| 8103 "dimensions must match existing texture level dimensions"); |
| 8104 return false; |
| 8105 } |
| 8106 return ValidateCompressedTexDimensions( |
| 8107 function_name, level, width, height, format); |
| 8108 } |
8054 default: | 8109 default: |
8055 return false; | 8110 return false; |
8056 } | 8111 } |
8057 } | 8112 } |
8058 | 8113 |
8059 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( | 8114 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( |
8060 GLenum target, | 8115 GLenum target, |
8061 GLint level, | 8116 GLint level, |
8062 GLenum internal_format, | 8117 GLenum internal_format, |
8063 GLsizei width, | 8118 GLsizei width, |
(...skipping 2678 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 |