diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-17 04:51:40 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-17 04:51:40 +0000 |
commit | 07d0cc8a31252167f8568b3103218aeefd2f8f03 (patch) | |
tree | 5a970ff9158373a14fa528354470b6d0f2bb2126 /gpu | |
parent | 349a9a34325fbbb74031803f4e37e321fa621e0e (diff) | |
download | chromium_src-07d0cc8a31252167f8568b3103218aeefd2f8f03.zip chromium_src-07d0cc8a31252167f8568b3103218aeefd2f8f03.tar.gz chromium_src-07d0cc8a31252167f8568b3103218aeefd2f8f03.tar.bz2 |
Updates many commands to require the client to set the
result->size to 0 or result->success to false before
calling the command.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/612006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39193 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/service/common_decoder.cc | 4 | ||||
-rw-r--r-- | gpu/command_buffer/service/common_decoder_unittest.cc | 22 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 26 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc | 102 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.cc | 6 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.h | 48 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager_unittest.cc | 198 |
7 files changed, 383 insertions, 23 deletions
diff --git a/gpu/command_buffer/service/common_decoder.cc b/gpu/command_buffer/service/common_decoder.cc index 3dbe967..4452e39 100644 --- a/gpu/command_buffer/service/common_decoder.cc +++ b/gpu/command_buffer/service/common_decoder.cc @@ -272,6 +272,10 @@ error::Error CommonDecoder::HandleGetBucketSize( if (!data) { return error::kInvalidArguments; } + // Check that the client initialized the result. + if (*data != 0) { + return error::kInvalidArguments; + } Bucket* bucket = GetBucket(bucket_id); if (!bucket) { return error::kInvalidArguments; diff --git a/gpu/command_buffer/service/common_decoder_unittest.cc b/gpu/command_buffer/service/common_decoder_unittest.cc index bdab529..c71c92e 100644 --- a/gpu/command_buffer/service/common_decoder_unittest.cc +++ b/gpu/command_buffer/service/common_decoder_unittest.cc @@ -209,6 +209,9 @@ TEST_F(CommonDecoderTest, Jump) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(MockCommandBufferEngine::kValidOffset, engine_.GetGetOffset()); + // Check negative offset fails + cmd.Init(-1); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } // NOTE: The read_pointer checks for relative commands do not take into account @@ -236,6 +239,10 @@ TEST_F(CommonDecoderTest, JumpRelative) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); // See note above. EXPECT_EQ(read_pointer + kNegativeOffset, engine_.GetGetOffset()); + // Check invalid negative offset fails. + const int32 kInvalidNegativeOffset = -kPositiveOffset + kNegativeOffset - 1; + cmd.Init(kInvalidNegativeOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } TEST_F(CommonDecoderTest, Call) { @@ -250,6 +257,9 @@ TEST_F(CommonDecoderTest, Call) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(MockCommandBufferEngine::kValidOffset, engine_.GetGetOffset()); + // Check negative offset fails + cmd.Init(-1); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); // Check that the call values are on the stack. cmd::Return return_cmd; return_cmd.Init(); @@ -284,6 +294,10 @@ TEST_F(CommonDecoderTest, CallRelative) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); // See note above. EXPECT_EQ(read_pointer_2 + kNegativeOffset, engine_.GetGetOffset()); + // Check invalid negative offset fails. + const int32 kInvalidNegativeOffset = -kPositiveOffset + kNegativeOffset - 1; + cmd.Init(kInvalidNegativeOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); // Check that the call values are on the stack. cmd::Return return_cmd; @@ -466,7 +480,7 @@ TEST_F(CommonDecoderTest, GetBucketSize) { const uint32 kSomeOffsetInSharedMemory = 50; uint32* memory = engine_.GetSharedMemoryAs<uint32*>(kSomeOffsetInSharedMemory); - *memory = 0xFFFFFFFF; + *memory = 0x0; cmd.Init(kBucketId, MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -476,6 +490,12 @@ TEST_F(CommonDecoderTest, GetBucketSize) { cmd.Init(kInvalidBucketId, MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + + // Check that it fails if the result size is not set to zero + *memory = 0x1; + cmd.Init(kBucketId, + MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } TEST_F(CommonDecoderTest, GetBucketData) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index a644bb2..9ea66c6 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -1374,7 +1374,7 @@ void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint texture) { return; } if (info->target() == 0) { - info->SetTarget(target, texture_manager_->MaxLevelsForTarget(target)); + texture_manager_->SetInfoTarget(info, target); } } glBindTexture(target, texture); @@ -2186,7 +2186,10 @@ error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv( if (!result) { return error::kOutOfBounds; } - result->size = 0; + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } if (!ValidateGLenumVertexPointer(pname)) { SetGLError(GL_INVALID_ENUM); return error::kNoError; @@ -2293,9 +2296,12 @@ error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat( if (!result) { return error::kOutOfBounds; } + // Check that the client initialized the result. + if (result->success != 0) { + return error::kInvalidArguments; + } if (!ValidateGLenumShaderType(shader_type) || !ValidateGLenumShaderPrecision(precision_type)) { - result->success = 0; // false SetGLError(GL_INVALID_ENUM); } else { result->success = 1; // true @@ -2336,6 +2342,10 @@ error::Error GLES2DecoderImpl::HandleGetAttachedShaders( if (!result) { return error::kOutOfBounds; } + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } GLsizei count = 0; glGetAttachedShaders(service_id, max_count, &count, result->GetData()); for (GLsizei ii = 0; ii < count; ++ii) { @@ -2361,7 +2371,10 @@ error::Error GLES2DecoderImpl::HandleGetActiveUniform( if (!result) { return error::kOutOfBounds; } - result->success = 0; // false. + // Check that the client initialized the result. + if (result->success != 0) { + return error::kInvalidArguments; + } if (!id_manager_->GetServiceId(program, &service_id)) { SetGLError(GL_INVALID_VALUE); return error::kNoError; @@ -2398,7 +2411,10 @@ error::Error GLES2DecoderImpl::HandleGetActiveAttrib( if (!result) { return error::kOutOfBounds; } - result->success = 0; // false. + // Check that the client initialized the result. + if (result->success != 0) { + return error::kInvalidArguments; + } if (!id_manager_->GetServiceId(program, &service_id)) { SetGLError(GL_INVALID_VALUE); return error::kNoError; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index a583056..a656d13 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -914,6 +914,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervSucceeds) { const GLuint kIndexToTest = 1; GetVertexAttribPointerv::Result* result = static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_); + result->size = 0; const GLuint* result_value = result->GetData(); // Test that initial value is 0. GetVertexAttribPointerv cmd; @@ -927,6 +928,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervSucceeds) { // Set the value and see that we get it. SetupVertexBuffer(); DoVertexAttribPointer(kIndexToTest, 2, GL_FLOAT, 0, kOffsetToTestFor); + result->size = 0; EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(sizeof(*result_value), result->size); EXPECT_EQ(kOffsetToTestFor, *result_value); @@ -937,6 +939,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervBadArgsFails) { const GLuint kIndexToTest = 1; GetVertexAttribPointerv::Result* result = static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_); + result->size = 0; const GLuint* result_value = result->GetData(); // Test pname invalid fails. GetVertexAttribPointerv cmd; @@ -948,6 +951,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervBadArgsFails) { EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); // Test index out of range fails. + result->size = 0; cmd.Init(kNumVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_POINTER, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -969,6 +973,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervBadArgsFails) { TEST_F(GLES2DecoderWithShaderTest, GetUniformivSucceeds) { GetUniformiv::Result* result = static_cast<GetUniformiv::Result*>(shared_memory_address_); + result->size = 0; GetUniformiv cmd; cmd.Init(client_program_id_, kUniform2Location, kSharedMemoryId, kSharedMemoryOffset); @@ -981,6 +986,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformivSucceeds) { TEST_F(GLES2DecoderWithShaderTest, GetUniformivArrayElementSucceeds) { GetUniformiv::Result* result = static_cast<GetUniformiv::Result*>(shared_memory_address_); + result->size = 0; GetUniformiv cmd; cmd.Init(client_program_id_, kUniform2ElementLocation, kSharedMemoryId, kSharedMemoryOffset); @@ -994,6 +1000,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformivArrayElementSucceeds) { TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) { GetUniformiv::Result* result = static_cast<GetUniformiv::Result*>(shared_memory_address_); + result->size = 0; GetUniformiv cmd; // non-existant program cmd.Init(kInvalidClientId, kUniform2Location, @@ -1030,6 +1037,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) { TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadLocationFails) { GetUniformiv::Result* result = static_cast<GetUniformiv::Result*>(shared_memory_address_); + result->size = 0; GetUniformiv cmd; // invalid location cmd.Init(client_program_id_, kInvalidUniformLocation, @@ -1056,6 +1064,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadSharedMemoryFails) { TEST_F(GLES2DecoderWithShaderTest, GetUniformfvSucceeds) { GetUniformfv::Result* result = static_cast<GetUniformfv::Result*>(shared_memory_address_); + result->size = 0; GetUniformfv cmd; cmd.Init(client_program_id_, kUniform2Location, kSharedMemoryId, kSharedMemoryOffset); @@ -1068,6 +1077,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformfvSucceeds) { TEST_F(GLES2DecoderWithShaderTest, GetUniformfvArrayElementSucceeds) { GetUniformfv::Result* result = static_cast<GetUniformfv::Result*>(shared_memory_address_); + result->size = 0; GetUniformfv cmd; cmd.Init(client_program_id_, kUniform2ElementLocation, kSharedMemoryId, kSharedMemoryOffset); @@ -1081,6 +1091,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformfvArrayElementSucceeds) { TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) { GetUniformfv::Result* result = static_cast<GetUniformfv::Result*>(shared_memory_address_); + result->size = 0; GetUniformfv cmd; // non-existant program cmd.Init(kInvalidClientId, kUniform2Location, @@ -1117,6 +1128,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) { TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadLocationFails) { GetUniformfv::Result* result = static_cast<GetUniformfv::Result*>(shared_memory_address_); + result->size = 0; GetUniformfv cmd; // invalid location cmd.Init(client_program_id_, kInvalidUniformLocation, @@ -1144,6 +1156,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersSucceeds) { GetAttachedShaders cmd; typedef GetAttachedShaders::Result Result; Result* result = static_cast<Result*>(shared_memory_address_); + result->size = 0; EXPECT_CALL(*gl_, GetAttachedShaders(kServiceProgramId, 1, _, _)) .WillOnce(DoAll(SetArgumentPointee<2>(1), SetArgumentPointee<3>(kServiceShaderId))); @@ -1155,10 +1168,23 @@ TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersSucceeds) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersResultNotInitFail) { + GetAttachedShaders cmd; + typedef GetAttachedShaders::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->size = 1; + EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _)) + .Times(0); + cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_, + Result::ComputeSize(1)); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersBadProgramFails) { GetAttachedShaders cmd; typedef GetAttachedShaders::Result Result; Result* result = static_cast<Result*>(shared_memory_address_); + result->size = 0; EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _)) .Times(0); cmd.Init(kInvalidClientId, shared_memory_id_, shared_memory_offset_, @@ -1185,6 +1211,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatSucceeds) { GetShaderPrecisionFormat cmd; typedef GetShaderPrecisionFormat::Result Result; Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 0; // NOTE: GL will not be called. There is no equivalent Desktop OpenGL // function. cmd.Init(GL_VERTEX_SHADER, GL_HIGH_FLOAT, @@ -1197,12 +1224,28 @@ TEST_F(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatSucceeds) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +TEST_F(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatResultNotInitFails) { + GetShaderPrecisionFormat cmd; + typedef GetShaderPrecisionFormat::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 1; + // NOTE: GL will not be called. There is no equivalent Desktop OpenGL + // function. + cmd.Init(GL_VERTEX_SHADER, GL_HIGH_FLOAT, + shared_memory_id_, shared_memory_offset_); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + TEST_F(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatBadArgsFails) { + typedef GetShaderPrecisionFormat::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 0; GetShaderPrecisionFormat cmd; cmd.Init(GL_TEXTURE_2D, GL_HIGH_FLOAT, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); + result->success = 0; cmd.Init(GL_VERTEX_SHADER, GL_TEXTURE_2D, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1226,6 +1269,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformSucceeds) { GetActiveUniform cmd; typedef GetActiveUniform::Result Result; Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 0; cmd.Init(client_program_id_, kUniformIndex, kBucketId, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1239,17 +1283,31 @@ TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformSucceeds) { bucket->size())); } +TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformResultNotInitFails) { + const GLuint kUniformIndex = 1; + const uint32 kBucketId = 123; + GetActiveUniform cmd; + typedef GetActiveUniform::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 1; + cmd.Init(client_program_id_, kUniformIndex, kBucketId, + shared_memory_id_, shared_memory_offset_); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformBadProgramFails) { const GLuint kUniformIndex = 1; const uint32 kBucketId = 123; GetActiveUniform cmd; typedef GetActiveUniform::Result Result; Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 0; cmd.Init(kInvalidClientId, kUniformIndex, kBucketId, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0, result->success); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + result->success = 0; cmd.Init(client_texture_id_, kUniformIndex, kBucketId, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1262,6 +1320,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformBadIndexFails) { GetActiveUniform cmd; typedef GetActiveUniform::Result Result; Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 0; cmd.Init(client_program_id_, kBadUniformIndex, kBucketId, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1288,6 +1347,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribSucceeds) { GetActiveAttrib cmd; typedef GetActiveAttrib::Result Result; Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 0; cmd.Init(client_program_id_, kAttribIndex, kBucketId, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1301,17 +1361,31 @@ TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribSucceeds) { bucket->size())); } +TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribResultNotInitFails) { + const GLuint kAttribIndex = 1; + const uint32 kBucketId = 123; + GetActiveAttrib cmd; + typedef GetActiveAttrib::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 1; + cmd.Init(client_program_id_, kAttribIndex, kBucketId, + shared_memory_id_, shared_memory_offset_); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadProgramFails) { const GLuint kAttribIndex = 1; const uint32 kBucketId = 123; GetActiveAttrib cmd; typedef GetActiveAttrib::Result Result; Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 0; cmd.Init(kInvalidClientId, kAttribIndex, kBucketId, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0, result->success); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + result->success = 0; cmd.Init(client_texture_id_, kAttribIndex, kBucketId, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1324,6 +1398,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadIndexFails) { GetActiveAttrib cmd; typedef GetActiveAttrib::Result Result; Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 0; cmd.Init(client_program_id_, kBadAttribIndex, kBucketId, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1438,6 +1513,19 @@ TEST_F(GLES2DecoderTest, ShaderSourceImmediateInvalidArgs) { EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } +TEST_F(GLES2DecoderTest, GenerateMipmapWrongFormatsFails) { + EXPECT_CALL(*gl_, GenerateMipmapEXT(_)) + .Times(0); + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + DoTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_UNSIGNED_BYTE, + 0, 0); + GenerateMipmap cmd; + cmd.Init(GL_TEXTURE_2D); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + // TODO(gman): BindAttribLocation // TODO(gman): BindAttribLocationImmediate @@ -1474,6 +1562,20 @@ TEST_F(GLES2DecoderTest, ShaderSourceImmediateInvalidArgs) { // TODO(gman): ReadPixels +// TODO(gman): TexImage2D + +// TODO(gman): TexImage2DImmediate + +// TODO(gman): TexSubImage2D + +// TODO(gman): TexSubImage2DImmediate + +// TODO(gman): UseProgram + +// TODO(gman): SwapBuffers + +// TODO(gman): VertexAttribPointer + #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_autogen.h" } // namespace gles2 diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index 91b3462..1496f88 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc @@ -147,7 +147,7 @@ void TextureManager::TextureInfo::Update() { } } - // Update texture_complete status. + // Update texture_complete and cube_complete status. const TextureInfo::LevelInfo& first_face = level_infos_[0][0]; texture_complete_ = (max_level_set_ == ComputeMipMapCount(first_face.width, @@ -157,7 +157,7 @@ void TextureManager::TextureInfo::Update() { cube_complete_ = (level_infos_.size() == 6) && (first_face.width == first_face.height); for (size_t ii = 0; - ii < level_infos_.size() && cube_complete_ && texture_complete_; + ii < level_infos_.size() && (cube_complete_ || texture_complete_); ++ii) { const TextureInfo::LevelInfo& level0 = level_infos_[ii][0]; if (!level0.valid || @@ -173,7 +173,7 @@ void TextureManager::TextureInfo::Update() { GLsizei width = level0.width; GLsizei height = level0.height; GLsizei depth = level0.depth; - for (GLint jj = 0; jj <= max_level_set_; ++jj) { + for (GLint jj = 1; jj <= max_level_set_; ++jj) { // compute required size for mip. width = std::max(1, width >> 1); height = std::max(1, height >> 1); diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h index 0562416..efb08f0 100644 --- a/gpu/command_buffer/service/texture_manager.h +++ b/gpu/command_buffer/service/texture_manager.h @@ -40,16 +40,6 @@ class TextureManager { return target_; } - void SetTarget(GLenum target, GLint max_levels) { - DCHECK_EQ(0u, target_); // you can only set this once. - target_ = target; - size_t num_faces = (target == GL_TEXTURE_2D) ? 1 : 6; - level_infos_.resize(num_faces); - for (size_t ii = 0; ii < num_faces; ++ii) { - level_infos_[ii].resize(max_levels); - } - } - // In GLES2 "texture complete" means it has all required mips for filtering // down to a 1x1 pixel texture, they are in the correct order, they are all // the same format. @@ -57,6 +47,12 @@ class TextureManager { return texture_complete_; } + // In GLES2 "cube complete" means all 6 faces level 0 are defined, all the + // same format, all the same dimensions and all width = height. + bool cube_complete() const { + return cube_complete_; + } + // Whether or not this texture is a non-power-of-two texture. bool npot() const { return npot_; @@ -80,7 +76,9 @@ class TextureManager { GLenum format, GLenum type); - protected: + private: + friend class TextureManager; + struct LevelInfo { LevelInfo() : valid(false), @@ -103,7 +101,20 @@ class TextureManager { GLenum type; }; - private: + // Sets the TextureInfo's target + // Parameters: + // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP + // max_levels: The maximum levels this type of target can have. + void SetTarget(GLenum target, GLint max_levels) { + DCHECK_EQ(0u, target_); // you can only set this once. + target_ = target; + size_t num_faces = (target == GL_TEXTURE_2D) ? 1 : 6; + level_infos_.resize(num_faces); + for (size_t ii = 0; ii < num_faces; ++ii) { + level_infos_[ii].resize(max_levels); + } + } + // Update info about this texture. void Update(); @@ -156,7 +167,18 @@ class TextureManager { level < MaxLevelsForTarget(target) && width <= max_size && height <= max_size && - depth <= max_size; + depth <= max_size && + (target != GL_TEXTURE_CUBE_MAP || (width == height && depth == 1)) && + (target != GL_TEXTURE_2D || (depth == 1)); + } + + // Sets the TextureInfo's target + // Parameters: + // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP + // max_levels: The maximum levels this type of target can have. + void SetInfoTarget(TextureInfo* info, GLenum target) { + DCHECK(info); + info->SetTarget(target, MaxLevelsForTarget(target)); } // Creates a new texture info. diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc index a4212cd..8bf2814 100644 --- a/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/gpu/command_buffer/service/texture_manager_unittest.cc @@ -12,6 +12,8 @@ class TextureManagerTest : public testing::Test { public: static const GLint kMaxTextureSize = 16; static const GLint kMaxCubeMapTextureSize = 8; + static const GLint kMax2dLevels = 5; + static const GLint kMaxCubeMapLevels = 4; TextureManagerTest() : manager_(kMaxTextureSize, kMaxCubeMapTextureSize) { @@ -45,7 +47,201 @@ TEST_F(TextureManagerTest, Basic) { EXPECT_TRUE(manager_.GetTextureInfo(kTexture1Id) == NULL); } -// TODO(gman): Test TextureInfo setting. +TEST_F(TextureManagerTest, MaxValues) { + // Check we get the right values for the max sizes. + EXPECT_EQ(kMax2dLevels, manager_.MaxLevelsForTarget(GL_TEXTURE_2D)); + EXPECT_EQ(kMaxCubeMapLevels, + manager_.MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP)); + EXPECT_EQ(kMaxTextureSize, manager_.MaxSizeForTarget(GL_TEXTURE_2D)); + EXPECT_EQ(kMaxCubeMapTextureSize, + manager_.MaxSizeForTarget(GL_TEXTURE_CUBE_MAP)); +} + +TEST_F(TextureManagerTest, ValidForTexture) { + // check 2d + EXPECT_TRUE(manager_.ValidForTarget( + GL_TEXTURE_2D, 0, + kMaxTextureSize, kMaxTextureSize, 1)); + EXPECT_TRUE(manager_.ValidForTarget( + GL_TEXTURE_2D, kMax2dLevels - 1, + kMaxTextureSize, kMaxTextureSize, 1)); + EXPECT_TRUE(manager_.ValidForTarget( + GL_TEXTURE_2D, kMax2dLevels - 1, + 1, kMaxTextureSize, 1)); + EXPECT_TRUE(manager_.ValidForTarget( + GL_TEXTURE_2D, kMax2dLevels - 1, + kMaxTextureSize, 1, 1)); + // check level out of range. + EXPECT_FALSE(manager_.ValidForTarget( + GL_TEXTURE_2D, kMax2dLevels, + kMaxTextureSize, 1, 1)); + // check has depth. + EXPECT_FALSE(manager_.ValidForTarget( + GL_TEXTURE_2D, kMax2dLevels, + kMaxTextureSize, 1, 2)); + + // check cube + EXPECT_TRUE(manager_.ValidForTarget( + GL_TEXTURE_CUBE_MAP, 0, + kMaxCubeMapTextureSize, kMaxCubeMapTextureSize, 1)); + EXPECT_TRUE(manager_.ValidForTarget( + GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels - 1, + kMaxCubeMapTextureSize, kMaxCubeMapTextureSize, 1)); + // check level out of range. + EXPECT_FALSE(manager_.ValidForTarget( + GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels, + kMaxCubeMapTextureSize, 1, 1)); + // check not square. + EXPECT_FALSE(manager_.ValidForTarget( + GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels, + kMaxCubeMapTextureSize, 1, 1)); + // check has depth. + EXPECT_FALSE(manager_.ValidForTarget( + GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels, + kMaxCubeMapTextureSize, 1, 2)); +} + +class TextureInfoTest : public testing::Test { + public: + static const GLint kMaxTextureSize = 16; + static const GLint kMaxCubeMapTextureSize = 8; + static const GLint kMax2dLevels = 5; + static const GLint kMaxCubeMapLevels = 4; + static const GLuint kTexture1Id = 1; + + TextureInfoTest() + : manager_(kMaxTextureSize, kMaxCubeMapTextureSize) { + } + + protected: + virtual void SetUp() { + manager_.CreateTextureInfo(kTexture1Id); + info_ = manager_.GetTextureInfo(kTexture1Id); + ASSERT_TRUE(info_ != NULL); + } + + virtual void TearDown() { + } + + TextureManager manager_; + TextureManager::TextureInfo* info_; +}; + +TEST_F(TextureInfoTest, POT2D) { + manager_.SetInfoTarget(info_, GL_TEXTURE_2D); + EXPECT_EQ(GL_TEXTURE_2D, info_->target()); + // Check Setting level 0 to POT + info_->SetLevelInfo( + GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_FALSE(info_->npot()); + EXPECT_FALSE(info_->texture_complete()); + EXPECT_TRUE(info_->CanGenerateMipmaps()); + // Make mips. + info_->MarkMipmapsGenerated(); + EXPECT_TRUE(info_->texture_complete()); + // Change a mip. + info_->SetLevelInfo( + GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_FALSE(info_->npot()); + EXPECT_FALSE(info_->texture_complete()); + EXPECT_TRUE(info_->CanGenerateMipmaps()); + // Set a level past the number of mips that would get generated. + info_->SetLevelInfo( + GL_TEXTURE_2D, 3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_TRUE(info_->CanGenerateMipmaps()); + // Make mips. + info_->MarkMipmapsGenerated(); + EXPECT_FALSE(info_->texture_complete()); +} + +TEST_F(TextureInfoTest, NPOT2D) { + manager_.SetInfoTarget(info_, GL_TEXTURE_2D); + EXPECT_EQ(GL_TEXTURE_2D, info_->target()); + // Check Setting level 0 to NPOT + info_->SetLevelInfo( + GL_TEXTURE_2D, 0, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_TRUE(info_->npot()); + EXPECT_FALSE(info_->texture_complete()); + EXPECT_FALSE(info_->CanGenerateMipmaps()); + // Change it to POT. + info_->SetLevelInfo( + GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_FALSE(info_->npot()); + EXPECT_FALSE(info_->texture_complete()); + EXPECT_TRUE(info_->CanGenerateMipmaps()); +} + +TEST_F(TextureInfoTest, POTCubeMap) { + manager_.SetInfoTarget(info_, GL_TEXTURE_CUBE_MAP); + EXPECT_EQ(GL_TEXTURE_CUBE_MAP, info_->target()); + // Check Setting level 0 each face to POT + info_->SetLevelInfo( + GL_TEXTURE_CUBE_MAP_POSITIVE_X, + 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_FALSE(info_->npot()); + EXPECT_FALSE(info_->texture_complete()); + EXPECT_FALSE(info_->cube_complete()); + EXPECT_FALSE(info_->CanGenerateMipmaps()); + info_->SetLevelInfo( + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_FALSE(info_->npot()); + EXPECT_FALSE(info_->texture_complete()); + EXPECT_FALSE(info_->cube_complete()); + EXPECT_FALSE(info_->CanGenerateMipmaps()); + info_->SetLevelInfo( + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_FALSE(info_->npot()); + EXPECT_FALSE(info_->texture_complete()); + EXPECT_FALSE(info_->cube_complete()); + EXPECT_FALSE(info_->CanGenerateMipmaps()); + info_->SetLevelInfo( + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_FALSE(info_->npot()); + EXPECT_FALSE(info_->texture_complete()); + EXPECT_FALSE(info_->cube_complete()); + EXPECT_FALSE(info_->CanGenerateMipmaps()); + info_->SetLevelInfo( + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_FALSE(info_->npot()); + EXPECT_FALSE(info_->texture_complete()); + EXPECT_FALSE(info_->cube_complete()); + EXPECT_FALSE(info_->CanGenerateMipmaps()); + info_->SetLevelInfo( + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_FALSE(info_->npot()); + EXPECT_FALSE(info_->texture_complete()); + EXPECT_TRUE(info_->cube_complete()); + EXPECT_TRUE(info_->CanGenerateMipmaps()); + + // Make mips. + info_->MarkMipmapsGenerated(); + EXPECT_TRUE(info_->texture_complete()); + EXPECT_TRUE(info_->cube_complete()); + + // Change a mip. + info_->SetLevelInfo( + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + 1, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_FALSE(info_->npot()); + EXPECT_FALSE(info_->texture_complete()); + EXPECT_TRUE(info_->cube_complete()); + EXPECT_TRUE(info_->CanGenerateMipmaps()); + // Set a level past the number of mips that would get generated. + info_->SetLevelInfo( + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + 3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); + EXPECT_TRUE(info_->CanGenerateMipmaps()); + // Make mips. + info_->MarkMipmapsGenerated(); + EXPECT_FALSE(info_->texture_complete()); + EXPECT_TRUE(info_->cube_complete()); +} + } // namespace gles2 } // namespace gpu |