summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-17 04:51:40 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-17 04:51:40 +0000
commit07d0cc8a31252167f8568b3103218aeefd2f8f03 (patch)
tree5a970ff9158373a14fa528354470b6d0f2bb2126 /gpu
parent349a9a34325fbbb74031803f4e37e321fa621e0e (diff)
downloadchromium_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.cc4
-rw-r--r--gpu/command_buffer/service/common_decoder_unittest.cc22
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc26
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc102
-rw-r--r--gpu/command_buffer/service/texture_manager.cc6
-rw-r--r--gpu/command_buffer/service/texture_manager.h48
-rw-r--r--gpu/command_buffer/service/texture_manager_unittest.cc198
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