summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_unittest.cc13
-rw-r--r--gpu/command_buffer/service/feature_info.cc5
-rw-r--r--gpu/command_buffer/service/feature_info_unittest.cc18
-rw-r--r--gpu/command_buffer/service/gl_utils.h3
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc29
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc122
6 files changed, 183 insertions, 7 deletions
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc b/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc
index 0e157db..0eb908c 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc
+++ b/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc
@@ -234,6 +234,18 @@ TEST_F(GLES2UtilTest, RenderbufferBytesPerPixel) {
EXPECT_EQ(0u, GLES2Util::RenderbufferBytesPerPixel(-1));
}
+TEST_F(GLES2UtilTest, GetChannelsForCompressedFormat) {
+ EXPECT_EQ(0u, GLES2Util::GetChannelsForFormat(GL_ETC1_RGB8_OES));
+ EXPECT_EQ(0u, GLES2Util::GetChannelsForFormat(
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT));
+ EXPECT_EQ(0u, GLES2Util::GetChannelsForFormat(
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT));
+ EXPECT_EQ(0u, GLES2Util::GetChannelsForFormat(
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT));
+ EXPECT_EQ(0u, GLES2Util::GetChannelsForFormat(
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT));
+}
+
namespace {
void CheckParseUniformName(
@@ -278,4 +290,3 @@ TEST_F(GLES2UtilTest, ParseUniformName) {
} // namespace gles2
} // namespace gpu
-
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index a8c6679..7f15dbf 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -504,6 +504,11 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
validators_.g_l_state.AddValue(GL_TEXTURE_BINDING_EXTERNAL_OES);
}
+ if (ext.HaveAndDesire("GL_OES_compressed_ETC1_RGB8_texture")) {
+ AddExtensionString("GL_OES_compressed_ETC1_RGB8_texture");
+ validators_.compressed_texture_format.AddValue(GL_ETC1_RGB8_OES);
+ }
+
if (ext.Desire("GL_CHROMIUM_stream_texture")) {
AddExtensionString("GL_CHROMIUM_stream_texture");
feature_flags_.chromium_stream_texture = true;
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc
index a5cfa12..f08d4ce 100644
--- a/gpu/command_buffer/service/feature_info_unittest.cc
+++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -206,6 +206,8 @@ TEST_F(FeatureInfoTest, InitializeNoExtensions) {
Not(HasSubstr("GL_ANGLE_texture_usage")));
EXPECT_THAT(info_->extensions(),
Not(HasSubstr("GL_EXT_texture_storage")));
+ EXPECT_THAT(info_->extensions(),
+ Not(HasSubstr("GL_OES_compressed_ETC1_RGB8_texture")));
EXPECT_FALSE(info_->feature_flags().npot_ok);
EXPECT_FALSE(info_->feature_flags().chromium_webglsl);
EXPECT_FALSE(info_->validators()->compressed_texture_format.IsValid(
@@ -216,6 +218,8 @@ TEST_F(FeatureInfoTest, InitializeNoExtensions) {
GL_COMPRESSED_RGBA_S3TC_DXT3_EXT));
EXPECT_FALSE(info_->validators()->compressed_texture_format.IsValid(
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT));
+ EXPECT_FALSE(info_->validators()->compressed_texture_format.IsValid(
+ GL_ETC1_RGB8_OES));
EXPECT_FALSE(info_->validators()->read_pixel_format.IsValid(
GL_BGRA_EXT));
EXPECT_FALSE(info_->validators()->texture_parameter.IsValid(
@@ -702,6 +706,17 @@ TEST_F(FeatureInfoTest, InitializeOES_EGL_image_external) {
GL_TEXTURE_BINDING_EXTERNAL_OES));
}
+TEST_F(FeatureInfoTest, InitializeOES_compressed_ETC1_RGB8_texture) {
+ SetupInitExpectations("GL_OES_compressed_ETC1_RGB8_texture");
+ info_->Initialize(NULL);
+ EXPECT_THAT(info_->extensions(),
+ HasSubstr("GL_OES_compressed_ETC1_RGB8_texture"));
+ EXPECT_TRUE(info_->validators()->compressed_texture_format.IsValid(
+ GL_ETC1_RGB8_OES));
+ EXPECT_FALSE(info_->validators()->texture_internal_format.IsValid(
+ GL_ETC1_RGB8_OES));
+}
+
TEST_F(FeatureInfoTest, InitializeCHROMIUM_stream_texture) {
SetupInitExpectations("GL_CHROMIUM_stream_texture");
info_->Initialize(NULL);
@@ -852,6 +867,3 @@ TEST_F(FeatureInfoTest, IsAMDATI) {
} // namespace gles2
} // namespace gpu
-
-
-
diff --git a/gpu/command_buffer/service/gl_utils.h b/gpu/command_buffer/service/gl_utils.h
index e31126f..5baff01 100644
--- a/gpu/command_buffer/service/gl_utils.h
+++ b/gpu/command_buffer/service/gl_utils.h
@@ -101,6 +101,9 @@
// GL_OES_packed_depth_stencil
#define GL_DEPTH24_STENCIL8_OES 0x88F0
+// GL_OES_compressed_ETC1_RGB8_texture
+#define GL_ETC1_RGB8_OES 0x8D64
+
#define GL_GLEXT_PROTOTYPES 1
// GL_ARB_get_program_binary
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index a26c6b3..69df928 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -7080,6 +7080,9 @@ 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) ||
@@ -7114,6 +7117,15 @@ 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;
+ break;
+ }
default:
SetGLErrorInvalidEnum(function_name, format, "format");
return false;
@@ -7144,6 +7156,14 @@ bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
}
return true;
}
+ case GL_ETC1_RGB8_OES:
+ if (width <= 0 || height <= 0) {
+ SetGLError(
+ GL_INVALID_OPERATION, function_name,
+ "width or height invalid for level");
+ return false;
+ }
+ return true;
default:
return false;
}
@@ -7185,6 +7205,12 @@ bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
return ValidateCompressedTexDimensions(
function_name, level, width, height, format);
}
+ case GL_ETC1_RGB8_OES: {
+ SetGLError(
+ GL_INVALID_OPERATION, function_name,
+ "TexsubImage2d not supported for ECT1_RGB8_OES textures");
+ return false;
+ }
default:
return false;
}
@@ -7763,7 +7789,8 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D(
uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
- if ((channels_needed & channels_exist) != channels_needed) {
+ if (!channels_needed ||
+ (channels_needed & channels_exist) != channels_needed) {
SetGLError(
GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
return;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index af8b6b1..3a1f4c5 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -1866,7 +1866,7 @@ TEST_F(GLES2DecoderTest, GenerateMipmapHandlesOutOfMemory) {
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*gl_, GenerateMipmapEXT(GL_TEXTURE_2D))
- .Times(1);
+ .Times(1);
EXPECT_CALL(*gl_, TexParameteri(
GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR))
.Times(1)
@@ -5291,6 +5291,124 @@ TEST_F(GLES2DecoderManualInitTest, CompressedTexImage2DS3TC) {
}
}
+TEST_F(GLES2DecoderManualInitTest, CompressedTexImage2DETC1) {
+ InitDecoder(
+ "GL_OES_compressed_ETC1_RGB8_texture", // extensions
+ false, // has alpha
+ false, // has depth
+ false, // has stencil
+ false, // request alpha
+ false, // request depth
+ false, // request stencil
+ true); // bind generates resource
+ const uint32 kBucketId = 123;
+ CommonDecoder::Bucket* bucket = decoder_->CreateBucket(kBucketId);
+ ASSERT_TRUE(bucket != NULL);
+
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+
+ const GLenum kFormat = GL_ETC1_RGB8_OES;
+ const size_t kBlockSize = 8;
+
+ CompressedTexImage2DBucket cmd;
+ // test small width.
+ DoCompressedTexImage2D(GL_TEXTURE_2D, 0, kFormat, 4, 8, 0, 16, kBucketId);
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+ // test small height.
+ DoCompressedTexImage2D(GL_TEXTURE_2D, 0, kFormat, 8, 4, 0, 16, kBucketId);
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+ // test size too large.
+ cmd.Init(GL_TEXTURE_2D, 0, kFormat, 4, 4, 0, kBucketId);
+ bucket->SetSize(kBlockSize * 2);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+
+ // test size too small.
+ cmd.Init(GL_TEXTURE_2D, 0, kFormat, 4, 4, 0, kBucketId);
+ bucket->SetSize(kBlockSize / 2);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+
+ // Test a 16x16
+ DoCompressedTexImage2D(
+ GL_TEXTURE_2D, 0, kFormat, 16, 16, 0, kBlockSize * 16, kBucketId);
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+ // Test CompressedTexSubImage not allowed
+ CompressedTexSubImage2DBucket sub_cmd;
+ bucket->SetSize(kBlockSize);
+ sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 4, 4, kFormat, kBucketId);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+ // Test TexSubImage not allowed for ETC1 compressed texture
+ TextureManager::TextureInfo* info = GetTextureInfo(client_texture_id_);
+ ASSERT_TRUE(info != NULL);
+ GLenum type, internal_format;
+ EXPECT_TRUE(info->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
+ EXPECT_EQ(kFormat, internal_format);
+ TexSubImage2D texsub_cmd;
+ texsub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE,
+ kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(texsub_cmd));
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+ // Test CopyTexSubImage not allowed for ETC1 compressed texture
+ CopyTexSubImage2D copy_cmd;
+ copy_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_F(GLES2DecoderManualInitTest, GetCompressedTextureFormatsETC1) {
+ InitDecoder(
+ "GL_OES_compressed_ETC1_RGB8_texture", // extensions
+ false, // has alpha
+ false, // has depth
+ false, // has stencil
+ false, // request alpha
+ false, // request depth
+ false, // request stencil
+ true); // bind generates resource
+
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+
+ typedef GetIntegerv::Result Result;
+ Result* result = static_cast<Result*>(shared_memory_address_);
+ GetIntegerv cmd;
+ result->size = 0;
+ EXPECT_CALL(*gl_, GetIntegerv(_, _))
+ .Times(0)
+ .RetiresOnSaturation();
+ cmd.Init(
+ GL_NUM_COMPRESSED_TEXTURE_FORMATS,
+ shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(1, result->GetNumResults());
+ GLint num_formats = result->GetData()[0];
+ EXPECT_EQ(1, num_formats);
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+ result->size = 0;
+ cmd.Init(
+ GL_COMPRESSED_TEXTURE_FORMATS,
+ shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(num_formats, result->GetNumResults());
+
+ EXPECT_TRUE(ValueInArray(
+ GL_ETC1_RGB8_OES,
+ result->GetData(), result->GetNumResults()));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
TEST_F(GLES2DecoderWithShaderTest, GetProgramInfoCHROMIUMValidArgs) {
const uint32 kBucketId = 123;
GetProgramInfoCHROMIUM cmd;
@@ -5331,7 +5449,7 @@ TEST_F(GLES2DecoderManualInitTest, EGLImageExternalBindTexture) {
true); // bind generates resource
EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_EXTERNAL_OES, kNewServiceId));
EXPECT_CALL(*gl_, GenTextures(1, _))
- .WillOnce(SetArgumentPointee<1>(kNewServiceId));
+ .WillOnce(SetArgumentPointee<1>(kNewServiceId));
BindTexture cmd;
cmd.Init(GL_TEXTURE_EXTERNAL_OES, kNewClientId);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));