diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-16 02:41:58 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-16 02:41:58 +0000 |
commit | 7488d96ce5234f2e7435017c99a90d54aad7f99d (patch) | |
tree | 53588f3ad6c1154ae59f66e675ac2a9d9de91151 | |
parent | 9ecd399719439f11461912ee56a9d51763239a26 (diff) | |
download | chromium_src-7488d96ce5234f2e7435017c99a90d54aad7f99d.zip chromium_src-7488d96ce5234f2e7435017c99a90d54aad7f99d.tar.gz chromium_src-7488d96ce5234f2e7435017c99a90d54aad7f99d.tar.bz2 |
Adds support for OpenGL ES 2.0 extensions
this one specifically adds support for
GL_EXT_texture_compression_dxt1 and
GL_OES_texture_npot and
GL_EXT_texture_format_BGRA8888
TEST=unit tests
BUG=none
Review URL: http://codereview.chromium.org/2827051
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52598 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | gpu/GLES2/gles2_command_buffer.h | 3 | ||||
-rwxr-xr-x | gpu/command_buffer/build_gles2_cmd_buffer.py | 40 | ||||
-rw-r--r-- | gpu/command_buffer/service/context_group.cc | 47 | ||||
-rw-r--r-- | gpu/command_buffer/service/context_group.h | 10 | ||||
-rw-r--r-- | gpu/command_buffer/service/context_group_unittest.cc | 183 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 11 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc | 7 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h | 2 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_validation.h | 3 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_validation_autogen.h | 1 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h | 136 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.cc | 38 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.h | 18 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager_unittest.cc | 89 |
14 files changed, 455 insertions, 133 deletions
diff --git a/gpu/GLES2/gles2_command_buffer.h b/gpu/GLES2/gles2_command_buffer.h index c36b995..bf26a58 100644 --- a/gpu/GLES2/gles2_command_buffer.h +++ b/gpu/GLES2/gles2_command_buffer.h @@ -22,6 +22,9 @@ #ifndef GL_WRITE_ONLY #define GL_WRITE_ONLY 0x88B9 #endif +#ifndef GL_BGRA_EXT +#define GL_BGRA_EXT 0x80E1 +#endif #endif // GPU_GLES2_GLES2_COMMAND_BUFFER_H_ diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 4eee3aa..ef4a004 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -138,7 +138,7 @@ GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenumFaceType face, GLuint mask); GL_APICALL void GL_APIENTRY glStencilOp (GLenumStencilOp fail, GLenumStencilOp zfail, GLenumStencilOp zpass); GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenumFaceType face, GLenumStencilOp fail, GLenumStencilOp zfail, GLenumStencilOp zpass); -GL_APICALL void GL_APIENTRY glTexImage2D (GLenumTextureTarget target, GLint level, GLintTextureFormat internalformat, GLsizei width, GLsizei height, GLintTextureBorder border, GLenumTextureFormat format, GLenumPixelType type, const void* pixels); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenumTextureTarget target, GLint level, GLintTextureInternalFormat internalformat, GLsizei width, GLsizei height, GLintTextureBorder border, GLenumTextureFormat format, GLenumPixelType type, const void* pixels); GL_APICALL void GL_APIENTRY glTexParameterf (GLenumTextureBindTarget target, GLenumTextureParameter pname, GLfloat param); GL_APICALL void GL_APIENTRY glTexParameterfv (GLenumTextureBindTarget target, GLenumTextureParameter pname, const GLfloat* params); GL_APICALL void GL_APIENTRY glTexParameteri (GLenumTextureBindTarget target, GLenumTextureParameter pname, GLint param); @@ -429,10 +429,7 @@ _ENUM_LISTS = { }, 'CompressedTextureFormat': { 'type': 'GLenum', - # TODO(gman): Refactor validation code so these can be added at runtime 'valid': [ - 'GL_COMPRESSED_RGB_S3TC_DXT1_EXT', - 'GL_COMPRESSED_RGBA_S3TC_DXT1_EXT', ], }, 'GLState': { @@ -915,6 +912,20 @@ _ENUM_LISTS = { 'GL_BGR', ], }, + 'TextureInternalFormat': { + 'type': 'GLenum', + 'valid': [ + 'GL_ALPHA', + 'GL_LUMINANCE', + 'GL_LUMINANCE_ALPHA', + 'GL_RGB', + 'GL_RGBA', + ], + 'invalid': [ + 'GL_BGRA', + 'GL_BGR', + ], + }, 'VertexAttribType': { 'type': 'GLenum', 'valid': [ @@ -4991,12 +5002,13 @@ class GLGenerator(object): file = CHeaderWriter(filename) enums = sorted(_ENUM_LISTS.keys()) for enum in enums: - file.Write("static %s valid_%s_table[] = {\n" % - (_ENUM_LISTS[enum]['type'], ToUnderscore(enum))) - for value in _ENUM_LISTS[enum]['valid']: - file.Write(" %s,\n" % value) - file.Write("};\n") - file.Write("\n") + if len(_ENUM_LISTS[enum]['valid']) > 0: + file.Write("static %s valid_%s_table[] = {\n" % + (_ENUM_LISTS[enum]['type'], ToUnderscore(enum))) + for value in _ENUM_LISTS[enum]['valid']: + file.Write(" %s,\n" % value) + file.Write("};\n") + file.Write("\n") file.Write("Validators::Validators()\n") pre = ': ' post = ',' @@ -5005,8 +5017,12 @@ class GLGenerator(object): count += 1 if count == len(enums): post = ' {' - code = """ %(pre)s%(name)s( - valid_%(name)s_table, arraysize(valid_%(name)s_table))%(post)s + if len(_ENUM_LISTS[enum]['valid']) > 0: + code = """ %(pre)s%(name)s( + valid_%(name)s_table, arraysize(valid_%(name)s_table))%(post)s +""" + else: + code = """ %(pre)s%(name)s()%(post)s """ file.Write(code % { 'name': ToUnderscore(enum), diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index 4f30ad5..74ad556 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc @@ -46,6 +46,46 @@ bool ContextGroup::Initialize() { return true; } + // Figure out what extensions to turn on. + const char* extensions = + reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); + bool npot_ok = false; + + AddExtensionString("GL_CHROMIUM_map_sub"); + + // Check if we should allow GL_EXT_texture_compression_dxt1. + if (strstr(extensions, "GL_EXT_texture_compression_dxt1") || + strstr(extensions, "GL_EXT_texture_compression_s3tc")) { + AddExtensionString("GL_EXT_texture_compression_dxt1"); + validators_.compressed_texture_format.AddValue( + GL_COMPRESSED_RGB_S3TC_DXT1_EXT); + validators_.compressed_texture_format.AddValue( + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); + } + + // Check if we should allow GL_EXT_texture_format_BGRA8888 + if (strstr(extensions, "GL_EXT_texture_format_BGRA8888") || + strstr(extensions, "GL_APPLE_texture_format_BGRA8888") || + strstr(extensions, "GL_EXT_bgra")) { + AddExtensionString("GL_EXT_texture_format_BGRA8888"); + validators_.texture_internal_format.AddValue(GL_BGRA_EXT); + validators_.texture_format.AddValue(GL_BGRA_EXT); + } + + // Check if we should allow GL_OES_texture_npot + if (strstr(extensions, "GL_ARB_texture_non_power_of_two") || + strstr(extensions, "GL_OES_texture_npot")) { + AddExtensionString("GL_OES_texture_npot"); + npot_ok = true; + } + + // TODO(gman): Add support for these extensions. + // GL_OES_depth24 + // GL_OES_depth32 + // GL_OES_packed_depth_stencil + // GL_OES_element_index_uint + // GL_EXT_texture_format_BGRA8888 + buffer_manager_.reset(new BufferManager()); framebuffer_manager_.reset(new FramebufferManager()); renderbuffer_manager_.reset(new RenderbufferManager()); @@ -65,7 +105,8 @@ bool ContextGroup::Initialize() { GLint max_cube_map_texture_size; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size); - texture_manager_.reset(new TextureManager(max_texture_size, + texture_manager_.reset(new TextureManager(npot_ok, + max_texture_size, max_cube_map_texture_size)); GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_image_units_); @@ -126,6 +167,10 @@ void ContextGroup::Destroy(bool have_context) { } } +void ContextGroup::AddExtensionString(const std::string& str) { + extensions_ += (extensions_.empty() ? " " : "") + str; +} + IdAllocator* ContextGroup::GetIdAllocator(unsigned namespace_id) { IdAllocatorMap::iterator it = id_namespaces_.find(namespace_id); if (it != id_namespaces_.end()) { diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h index 21fc061..a38f369 100644 --- a/gpu/command_buffer/service/context_group.h +++ b/gpu/command_buffer/service/context_group.h @@ -6,6 +6,7 @@ #define GPU_COMMAND_BUFFER_SERVICE_CONTEXT_GROUP_H_ #include <map> +#include <string> #include "base/basictypes.h" #include "base/linked_ptr.h" #include "base/scoped_ptr.h" @@ -96,7 +97,13 @@ class ContextGroup { return &validators_; } + const std::string& extensions() const { + return extensions_; + } + private: + void AddExtensionString(const std::string& str); + // Whether or not this context is initialized. bool initialized_; @@ -125,6 +132,9 @@ class ContextGroup { Validators validators_; + // The extensions string returned by glGetString(GL_EXTENSIONS); + std::string extensions_; + DISALLOW_COPY_AND_ASSIGN(ContextGroup); }; diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc index c997f7a..e053127 100644 --- a/gpu/command_buffer/service/context_group_unittest.cc +++ b/gpu/command_buffer/service/context_group_unittest.cc @@ -3,8 +3,25 @@ // found in the LICENSE file. #include "gpu/command_buffer/service/context_group.h" +#include "app/gfx/gl/gl_mock.h" +#include "base/scoped_ptr.h" +#include "gpu/command_buffer/service/texture_manager.h" #include "testing/gtest/include/gtest/gtest.h" +using ::gfx::MockGLInterface; +using ::testing::_; +using ::testing::DoAll; +using ::testing::HasSubstr; +using ::testing::InSequence; +using ::testing::MatcherCast; +using ::testing::Not; +using ::testing::Pointee; +using ::testing::Return; +using ::testing::SetArrayArgument; +using ::testing::SetArgumentPointee; +using ::testing::StrEq; +using ::testing::StrictMock; + namespace gpu { namespace gles2 { @@ -13,16 +30,99 @@ class ContextGroupTest : public testing::Test { ContextGroupTest() { } + void SetupInitExpectations(const char* extensions); + protected: + static const GLint kMaxTextureSize = 2048; + static const GLint kMaxCubeMapTextureSize = 256; + static const GLint kNumVertexAttribs = 16; + static const GLint kNumTextureUnits = 8; + static const GLint kMaxTextureImageUnits = 8; + static const GLint kMaxVertexTextureImageUnits = 2; + static const GLint kMaxFragmentUniformVectors = 16; + static const GLint kMaxVaryingVectors = 8; + static const GLint kMaxVertexUniformVectors = 128; + virtual void SetUp() { + gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); + ::gfx::GLInterface::SetGLInterface(gl_.get()); } virtual void TearDown() { + group_.Destroy(false); + ::gfx::GLInterface::SetGLInterface(NULL); + gl_.reset(); } + scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; ContextGroup group_; }; +// GCC requires these declarations, but MSVC requires they not be present +#ifndef COMPILER_MSVC +const GLint ContextGroupTest::kMaxTextureSize; +const GLint ContextGroupTest::kMaxCubeMapTextureSize; +const GLint ContextGroupTest::kNumVertexAttribs; +const GLint ContextGroupTest::kNumTextureUnits; +const GLint ContextGroupTest::kMaxTextureImageUnits; +const GLint ContextGroupTest::kMaxVertexTextureImageUnits; +const GLint ContextGroupTest::kMaxFragmentUniformVectors; +const GLint ContextGroupTest::kMaxVaryingVectors; +const GLint ContextGroupTest::kMaxVertexUniformVectors; +#endif + +void ContextGroupTest::SetupInitExpectations(const char* extensions) { + InSequence sequence; + + EXPECT_CALL(*gl_, GetString(GL_EXTENSIONS)) + .WillOnce(Return(reinterpret_cast<const uint8*>(extensions))) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _)) + .WillOnce(SetArgumentPointee<1>(kNumVertexAttribs)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, _)) + .WillOnce(SetArgumentPointee<1>(kNumTextureUnits)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_TEXTURE_SIZE, _)) + .WillOnce(SetArgumentPointee<1>(kMaxTextureSize)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, _)) + .WillOnce(SetArgumentPointee<1>(kMaxCubeMapTextureSize)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxTextureImageUnits)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVertexTextureImageUnits)) + .RetiresOnSaturation(); + +#if defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) + + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformVectors * 4)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VARYING_VECTORS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVaryingVectors * 4)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformVectors * 4)) + .RetiresOnSaturation(); + +#else // !defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) + + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformVectors)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VARYING_FLOATS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVaryingVectors)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformVectors)) + .RetiresOnSaturation(); + +#endif // !defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) +} + TEST_F(ContextGroupTest, Basic) { // Test it starts off uninitialized. EXPECT_EQ(0u, group_.max_vertex_attribs()); @@ -40,6 +140,89 @@ TEST_F(ContextGroupTest, Basic) { EXPECT_TRUE(group_.shader_manager() == NULL); } +TEST_F(ContextGroupTest, InitializeNoExtensions) { + SetupInitExpectations(""); + group_.Initialize(); + // Check a couple of random extensions that should not be there. + EXPECT_THAT(group_.extensions(), Not(HasSubstr("GL_OES_texture_npot"))); + EXPECT_THAT(group_.extensions(), + Not(HasSubstr("GL_EXT_texture_compression_dxt1"))); + EXPECT_FALSE(group_.texture_manager()->npot_ok()); + EXPECT_FALSE(group_.validators()->compressed_texture_format.IsValid( + GL_COMPRESSED_RGB_S3TC_DXT1_EXT)); + EXPECT_FALSE(group_.validators()->compressed_texture_format.IsValid( + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)); +} + +TEST_F(ContextGroupTest, InitializeNPOTExtensionGLES) { + SetupInitExpectations("GL_OES_texture_npot"); + group_.Initialize(); + EXPECT_THAT(group_.extensions(), HasSubstr("GL_OES_texture_npot")); + EXPECT_TRUE(group_.texture_manager()->npot_ok()); +} + +TEST_F(ContextGroupTest, InitializeNPOTExtensionGL) { + SetupInitExpectations("GL_ARB_texture_non_power_of_two"); + group_.Initialize(); + EXPECT_THAT(group_.extensions(), HasSubstr("GL_OES_texture_npot")); + EXPECT_TRUE(group_.texture_manager()->npot_ok()); +} + +TEST_F(ContextGroupTest, InitializeDXTExtensionGLES2) { + SetupInitExpectations("GL_EXT_texture_compression_dxt1"); + group_.Initialize(); + EXPECT_THAT(group_.extensions(), + HasSubstr("GL_EXT_texture_compression_dxt1")); + EXPECT_TRUE(group_.validators()->compressed_texture_format.IsValid( + GL_COMPRESSED_RGB_S3TC_DXT1_EXT)); + EXPECT_TRUE(group_.validators()->compressed_texture_format.IsValid( + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)); +} + +TEST_F(ContextGroupTest, InitializeDXTExtensionGL) { + SetupInitExpectations("GL_EXT_texture_compression_s3tc"); + group_.Initialize(); + EXPECT_THAT(group_.extensions(), + HasSubstr("GL_EXT_texture_compression_dxt1")); + EXPECT_TRUE(group_.validators()->compressed_texture_format.IsValid( + GL_COMPRESSED_RGB_S3TC_DXT1_EXT)); + EXPECT_TRUE(group_.validators()->compressed_texture_format.IsValid( + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)); +} + +TEST_F(ContextGroupTest, InitializeEXT_texture_format_BGRA8888GLES2) { + SetupInitExpectations("GL_EXT_texture_format_BGRA8888"); + group_.Initialize(); + EXPECT_THAT(group_.extensions(), + HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE(group_.validators()->texture_format.IsValid( + GL_BGRA_EXT)); + EXPECT_TRUE(group_.validators()->texture_internal_format.IsValid( + GL_BGRA_EXT)); +} + +TEST_F(ContextGroupTest, InitializeEXT_texture_format_BGRA8888GL) { + SetupInitExpectations("GL_EXT_bgra"); + group_.Initialize(); + EXPECT_THAT(group_.extensions(), + HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE(group_.validators()->texture_format.IsValid( + GL_BGRA_EXT)); + EXPECT_TRUE(group_.validators()->texture_internal_format.IsValid( + GL_BGRA_EXT)); +} + +TEST_F(ContextGroupTest, InitializeEXT_texture_format_BGRA8888Apple) { + SetupInitExpectations("GL_APPLE_texture_format_BGRA8888"); + group_.Initialize(); + EXPECT_THAT(group_.extensions(), + HasSubstr("GL_EXT_texture_format_BGRA8888")); + EXPECT_TRUE(group_.validators()->texture_format.IsValid( + GL_BGRA_EXT)); + EXPECT_TRUE(group_.validators()->texture_internal_format.IsValid( + GL_BGRA_EXT)); +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index ceabfa7..e1df544 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -3006,7 +3006,7 @@ bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() { uniform_info->type == GL_SAMPLER_2D ? texture_unit.bound_texture_2d : texture_unit.bound_texture_cube_map; - if (!texture_info || !texture_info->CanRender()) { + if (!texture_info || !texture_info->CanRender(texture_manager())) { textures_set = true; glActiveTexture(GL_TEXTURE0 + texture_unit_index); glBindTexture( @@ -3039,7 +3039,7 @@ void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() { uniform_info->type == GL_SAMPLER_2D ? texture_unit.bound_texture_2d : texture_unit.bound_texture_cube_map; - if (!texture_info || !texture_info->CanRender()) { + if (!texture_info || !texture_info->CanRender(texture_manager())) { glActiveTexture(GL_TEXTURE0 + texture_unit_index); // Get the texture info that was previously bound here. texture_info = texture_unit.bind_target == GL_TEXTURE_2D ? @@ -4040,7 +4040,7 @@ error::Error GLES2DecoderImpl::HandleGetString( str = "OpenGL ES GLSL ES 1.0 Chromium"; break; case GL_EXTENSIONS: - str = ""; + str = group_->extensions().c_str(); break; default: str = gl_str; @@ -4323,6 +4323,11 @@ error::Error GLES2DecoderImpl::DoTexImage2D( } texture_manager()->SetLevelInfo(info, target, level, internal_format, width, height, 1, border, format, type); + #if !defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) + if (format == GL_BGRA_EXT && internal_format == GL_BGRA_EXT) { + internal_format = GL_RGBA; + } + #endif glTexImage2D( target, level, internal_format, width, height, border, format, type, pixels); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index ea1f056..c0ab738 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -30,11 +30,18 @@ namespace gpu { namespace gles2 { void GLES2DecoderTestBase::SetUp() { + InitDecoder(""); +} + +void GLES2DecoderTestBase::InitDecoder(const char* extensions) { gl_.reset(new StrictMock<MockGLInterface>()); ::gfx::GLInterface::SetGLInterface(gl_.get()); InSequence sequence; + EXPECT_CALL(*gl_, GetString(GL_EXTENSIONS)) + .WillOnce(Return(reinterpret_cast<const uint8*>(extensions))) + .RetiresOnSaturation(); EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _)) .WillOnce(SetArgumentPointee<1>(kNumVertexAttribs)) .RetiresOnSaturation(); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index 511be84..e9fe328 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -166,6 +166,8 @@ class GLES2DecoderTestBase : public testing::Test { void SetBucketAsCString(uint32 bucket_id, const char* str); + void InitDecoder(const char* extensions); + struct AttribInfo { const char* name; GLint size; diff --git a/gpu/command_buffer/service/gles2_cmd_validation.h b/gpu/command_buffer/service/gles2_cmd_validation.h index 77408a3..07ec6cd 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation.h +++ b/gpu/command_buffer/service/gles2_cmd_validation.h @@ -7,6 +7,7 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_H_ +#include <algorithm> #include <vector> #define GLES2_GPU_SERVICE 1 #include "gpu/command_buffer/common/gles2_cmd_format.h" @@ -18,6 +19,8 @@ namespace gles2 { template <typename T> class ValueValidator { public: + ValueValidator() {} + ValueValidator(const T* valid_values, int num_values) { for (int ii = 0; ii < num_values; ++ii) { AddValue(valid_values[ii]); diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index 6a617a6..f6500fd 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h @@ -44,6 +44,7 @@ ValueValidator<GLenum> string_type; ValueValidator<GLenum> texture_bind_target; ValueValidator<GLint> texture_border; ValueValidator<GLenum> texture_format; +ValueValidator<GLenum> texture_internal_format; ValueValidator<GLenum> texture_parameter; ValueValidator<GLenum> texture_target; ValueValidator<GLint> vertex_attrib_size; diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index 853f909..3b2407a 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -52,11 +52,6 @@ static GLenum valid_cmp_function_table[] = { GL_ALWAYS, }; -static GLenum valid_compressed_texture_format_table[] = { - GL_COMPRESSED_RGB_S3TC_DXT1_EXT, - GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, -}; - static GLenum valid_draw_mode_table[] = { GL_POINTS, GL_LINE_STRIP, @@ -361,6 +356,14 @@ static GLenum valid_texture_format_table[] = { GL_RGBA, }; +static GLenum valid_texture_internal_format_table[] = { + GL_ALPHA, + GL_LUMINANCE, + GL_LUMINANCE_ALPHA, + GL_RGB, + GL_RGBA, +}; + static GLenum valid_texture_parameter_table[] = { GL_TEXTURE_MAG_FILTER, GL_TEXTURE_MIN_FILTER, @@ -409,105 +412,112 @@ static GLenum valid_vertex_pointer_table[] = { Validators::Validators() : attachment( - valid_attachment_table, arraysize(valid_attachment_table)), + valid_attachment_table, arraysize(valid_attachment_table)), buffer_parameter( - valid_buffer_parameter_table, arraysize(valid_buffer_parameter_table)), + valid_buffer_parameter_table, arraysize( + valid_buffer_parameter_table)), buffer_target( - valid_buffer_target_table, arraysize(valid_buffer_target_table)), + valid_buffer_target_table, arraysize(valid_buffer_target_table)), buffer_usage( - valid_buffer_usage_table, arraysize(valid_buffer_usage_table)), + valid_buffer_usage_table, arraysize(valid_buffer_usage_table)), capability( - valid_capability_table, arraysize(valid_capability_table)), + valid_capability_table, arraysize(valid_capability_table)), cmp_function( - valid_cmp_function_table, arraysize(valid_cmp_function_table)), - compressed_texture_format( - valid_compressed_texture_format_table, arraysize( - valid_compressed_texture_format_table)), + valid_cmp_function_table, arraysize(valid_cmp_function_table)), + compressed_texture_format(), draw_mode( - valid_draw_mode_table, arraysize(valid_draw_mode_table)), + valid_draw_mode_table, arraysize(valid_draw_mode_table)), dst_blend_factor( - valid_dst_blend_factor_table, arraysize(valid_dst_blend_factor_table)), + valid_dst_blend_factor_table, arraysize( + valid_dst_blend_factor_table)), equation( - valid_equation_table, arraysize(valid_equation_table)), + valid_equation_table, arraysize(valid_equation_table)), face_mode( - valid_face_mode_table, arraysize(valid_face_mode_table)), + valid_face_mode_table, arraysize(valid_face_mode_table)), face_type( - valid_face_type_table, arraysize(valid_face_type_table)), + valid_face_type_table, arraysize(valid_face_type_table)), false_only( - valid_false_only_table, arraysize(valid_false_only_table)), + valid_false_only_table, arraysize(valid_false_only_table)), frame_buffer_parameter( - valid_frame_buffer_parameter_table, arraysize( - valid_frame_buffer_parameter_table)), + valid_frame_buffer_parameter_table, arraysize( + valid_frame_buffer_parameter_table)), frame_buffer_target( - valid_frame_buffer_target_table, arraysize( - valid_frame_buffer_target_table)), + valid_frame_buffer_target_table, arraysize( + valid_frame_buffer_target_table)), g_l_state( - valid_g_l_state_table, arraysize(valid_g_l_state_table)), + valid_g_l_state_table, arraysize(valid_g_l_state_table)), get_max_index_type( - valid_get_max_index_type_table, arraysize( - valid_get_max_index_type_table)), + valid_get_max_index_type_table, arraysize( + valid_get_max_index_type_table)), hint_mode( - valid_hint_mode_table, arraysize(valid_hint_mode_table)), + valid_hint_mode_table, arraysize(valid_hint_mode_table)), hint_target( - valid_hint_target_table, arraysize(valid_hint_target_table)), + valid_hint_target_table, arraysize(valid_hint_target_table)), index_type( - valid_index_type_table, arraysize(valid_index_type_table)), + valid_index_type_table, arraysize(valid_index_type_table)), pixel_store( - valid_pixel_store_table, arraysize(valid_pixel_store_table)), + valid_pixel_store_table, arraysize(valid_pixel_store_table)), pixel_store_alignment( - valid_pixel_store_alignment_table, arraysize( - valid_pixel_store_alignment_table)), + valid_pixel_store_alignment_table, arraysize( + valid_pixel_store_alignment_table)), pixel_type( - valid_pixel_type_table, arraysize(valid_pixel_type_table)), + valid_pixel_type_table, arraysize(valid_pixel_type_table)), program_parameter( - valid_program_parameter_table, arraysize( - valid_program_parameter_table)), + valid_program_parameter_table, arraysize( + valid_program_parameter_table)), read_pixel_format( - valid_read_pixel_format_table, arraysize( - valid_read_pixel_format_table)), + valid_read_pixel_format_table, arraysize( + valid_read_pixel_format_table)), render_buffer_format( - valid_render_buffer_format_table, arraysize( - valid_render_buffer_format_table)), + valid_render_buffer_format_table, arraysize( + valid_render_buffer_format_table)), render_buffer_parameter( - valid_render_buffer_parameter_table, arraysize( - valid_render_buffer_parameter_table)), + valid_render_buffer_parameter_table, arraysize( + valid_render_buffer_parameter_table)), render_buffer_target( - valid_render_buffer_target_table, arraysize( - valid_render_buffer_target_table)), + valid_render_buffer_target_table, arraysize( + valid_render_buffer_target_table)), shader_parameter( - valid_shader_parameter_table, arraysize(valid_shader_parameter_table)), + valid_shader_parameter_table, arraysize( + valid_shader_parameter_table)), shader_precision( - valid_shader_precision_table, arraysize(valid_shader_precision_table)), + valid_shader_precision_table, arraysize( + valid_shader_precision_table)), shader_type( - valid_shader_type_table, arraysize(valid_shader_type_table)), + valid_shader_type_table, arraysize(valid_shader_type_table)), src_blend_factor( - valid_src_blend_factor_table, arraysize(valid_src_blend_factor_table)), + valid_src_blend_factor_table, arraysize( + valid_src_blend_factor_table)), stencil_op( - valid_stencil_op_table, arraysize(valid_stencil_op_table)), + valid_stencil_op_table, arraysize(valid_stencil_op_table)), string_type( - valid_string_type_table, arraysize(valid_string_type_table)), + valid_string_type_table, arraysize(valid_string_type_table)), texture_bind_target( - valid_texture_bind_target_table, arraysize( - valid_texture_bind_target_table)), + valid_texture_bind_target_table, arraysize( + valid_texture_bind_target_table)), texture_border( - valid_texture_border_table, arraysize(valid_texture_border_table)), + valid_texture_border_table, arraysize(valid_texture_border_table)), texture_format( - valid_texture_format_table, arraysize(valid_texture_format_table)), + valid_texture_format_table, arraysize(valid_texture_format_table)), + texture_internal_format( + valid_texture_internal_format_table, arraysize( + valid_texture_internal_format_table)), texture_parameter( - valid_texture_parameter_table, arraysize( - valid_texture_parameter_table)), + valid_texture_parameter_table, arraysize( + valid_texture_parameter_table)), texture_target( - valid_texture_target_table, arraysize(valid_texture_target_table)), + valid_texture_target_table, arraysize(valid_texture_target_table)), vertex_attrib_size( - valid_vertex_attrib_size_table, arraysize( - valid_vertex_attrib_size_table)), + valid_vertex_attrib_size_table, arraysize( + valid_vertex_attrib_size_table)), vertex_attrib_type( - valid_vertex_attrib_type_table, arraysize( - valid_vertex_attrib_type_table)), + valid_vertex_attrib_type_table, arraysize( + valid_vertex_attrib_type_table)), vertex_attribute( - valid_vertex_attribute_table, arraysize(valid_vertex_attribute_table)), + valid_vertex_attribute_table, arraysize( + valid_vertex_attribute_table)), vertex_pointer( - valid_vertex_pointer_table, arraysize(valid_vertex_pointer_table)) { + valid_vertex_pointer_table, arraysize(valid_vertex_pointer_table)) { } #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_IMPLEMENTATION_AUTOGEN_H_ // NOLINT diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index da4b8a561..e822aa6 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc @@ -76,12 +76,14 @@ void TextureManager::Destroy(bool have_context) { } } -bool TextureManager::TextureInfo::CanRender() const { +bool TextureManager::TextureInfo::CanRender( + const TextureManager* manager) const { + DCHECK(manager); if (target_ == 0 || IsDeleted()) { return false; } bool needs_mips = NeedsMips(); - if (npot()) { + if (npot() && !manager->npot_ok()) { return !needs_mips && wrap_s_ == GL_CLAMP_TO_EDGE && wrap_t_ == GL_CLAMP_TO_EDGE; @@ -97,8 +99,9 @@ bool TextureManager::TextureInfo::CanRender() const { } } -bool TextureManager::TextureInfo::MarkMipmapsGenerated() { - if (!CanGenerateMipmaps()) { +bool TextureManager::TextureInfo::MarkMipmapsGenerated( + const TextureManager* manager) { + if (!CanGenerateMipmaps(manager)) { return false; } for (size_t ii = 0; ii < level_infos_.size(); ++ii) { @@ -126,8 +129,9 @@ bool TextureManager::TextureInfo::MarkMipmapsGenerated() { return true; } -bool TextureManager::TextureInfo::CanGenerateMipmaps() const { - if (npot() || level_infos_.empty() || IsDeleted()) { +bool TextureManager::TextureInfo::CanGenerateMipmaps( + const TextureManager* manager) const { + if ((npot() && !manager->npot_ok()) || level_infos_.empty() || IsDeleted()) { return false; } const TextureInfo::LevelInfo& first = level_infos_[0][0]; @@ -272,9 +276,11 @@ void TextureManager::TextureInfo::Update() { } TextureManager::TextureManager( + bool npot_ok, GLint max_texture_size, GLint max_cube_map_texture_size) - : max_texture_size_(max_texture_size), + : npot_ok_(npot_ok), + max_texture_size_(max_texture_size), max_cube_map_texture_size_(max_cube_map_texture_size), max_levels_(ComputeMipMapCount(max_texture_size, max_texture_size, @@ -329,13 +335,13 @@ void TextureManager::SetLevelInfo( GLenum type) { DCHECK(info); DCHECK(!info->IsDeleted()); - if (!info->CanRender()) { + if (!info->CanRender(this)) { --num_unrenderable_textures_; } info->SetLevelInfo( target, level, internal_format, width, height, depth, border, format, type); - if (!info->CanRender()) { + if (!info->CanRender(this)) { ++num_unrenderable_textures_; } } @@ -344,11 +350,11 @@ void TextureManager::SetParameter( TextureManager::TextureInfo* info, GLenum pname, GLint param) { DCHECK(info); DCHECK(!info->IsDeleted()); - if (!info->CanRender()) { + if (!info->CanRender(this)) { --num_unrenderable_textures_; } info->SetParameter(pname, param); - if (!info->CanRender()) { + if (!info->CanRender(this)) { ++num_unrenderable_textures_; } } @@ -356,11 +362,11 @@ void TextureManager::SetParameter( bool TextureManager::MarkMipmapsGenerated(TextureManager::TextureInfo* info) { DCHECK(info); DCHECK(!info->IsDeleted()); - if (!info->CanRender()) { + if (!info->CanRender(this)) { --num_unrenderable_textures_; } - bool result = info->MarkMipmapsGenerated(); - if (!info->CanRender()) { + bool result = info->MarkMipmapsGenerated(this); + if (!info->CanRender(this)) { ++num_unrenderable_textures_; } return result; @@ -372,7 +378,7 @@ TextureManager::TextureInfo* TextureManager::CreateTextureInfo( std::pair<TextureInfoMap::iterator, bool> result = texture_infos_.insert(std::make_pair(client_id, info)); DCHECK(result.second); - if (!info->CanRender()) { + if (!info->CanRender(this)) { ++num_unrenderable_textures_; } return info.get(); @@ -388,7 +394,7 @@ void TextureManager::RemoveTextureInfo(GLuint client_id) { TextureInfoMap::iterator it = texture_infos_.find(client_id); if (it != texture_infos_.end()) { TextureInfo* info = it->second; - if (!info->CanRender()) { + if (!info->CanRender(this)) { --num_unrenderable_textures_; } info->MarkAsDeleted(); diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h index 1df58c4..a984489 100644 --- a/gpu/command_buffer/service/texture_manager.h +++ b/gpu/command_buffer/service/texture_manager.h @@ -43,7 +43,7 @@ class TextureManager { // True if this texture meets all the GLES2 criteria for rendering. // See section 3.8.2 of the GLES2 spec. - bool CanRender() const; + bool CanRender(const TextureManager* manager) const; // The service side OpenGL id of the texture. GLuint service_id() const { @@ -76,7 +76,7 @@ class TextureManager { } // Returns true if mipmaps can be generated by GL. - bool CanGenerateMipmaps() const; + bool CanGenerateMipmaps(const TextureManager* manager) const; // Get the width and height for a particular level. Returns false if level // does not exist. @@ -132,7 +132,7 @@ class TextureManager { void SetParameter(GLenum pname, GLint param); // Makes each of the mip levels as though they were generated. - bool MarkMipmapsGenerated(); + bool MarkMipmapsGenerated(const TextureManager* manager); void MarkAsDeleted() { service_id_ = 0; @@ -193,13 +193,19 @@ class TextureManager { DISALLOW_COPY_AND_ASSIGN(TextureInfo); }; - TextureManager(GLsizei max_texture_size, + TextureManager(bool npot_ok, + GLsizei max_texture_size, GLsizei max_cube_map_texture_size); ~TextureManager(); // Must call before destruction. void Destroy(bool have_context); + // Whether or not npot textures can render. + bool npot_ok() const { + return npot_ok_; + } + // Returns the maximum number of levels. GLint MaxLevelsForTarget(GLenum target) const { return (target == GL_TEXTURE_2D) ? max_levels_ : max_cube_map_levels_; @@ -243,7 +249,8 @@ class TextureManager { void SetParameter(TextureInfo* info, GLenum pname, GLint param); // Makes each of the mip levels as though they were generated. - bool MarkMipmapsGenerated(TextureInfo* info); + // Returns false if that's not allowed for the given texture. + bool MarkMipmapsGenerated(TextureManager::TextureInfo* info); // Creates a new texture info. TextureInfo* CreateTextureInfo(GLuint client_id, GLuint service_id); @@ -272,6 +279,7 @@ class TextureManager { typedef std::map<GLuint, TextureInfo::Ref> TextureInfoMap; TextureInfoMap texture_infos_; + bool npot_ok_; GLsizei max_texture_size_; GLsizei max_cube_map_texture_size_; GLint max_levels_; diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc index 417454b..b97245c 100644 --- a/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/gpu/command_buffer/service/texture_manager_unittest.cc @@ -20,7 +20,7 @@ class TextureManagerTest : public testing::Test { static const GLint kMaxCubeMapLevels = 4; TextureManagerTest() - : manager_(kMaxTextureSize, kMaxCubeMapTextureSize) { + : manager_(false, kMaxTextureSize, kMaxCubeMapTextureSize) { } ~TextureManagerTest() { @@ -156,7 +156,7 @@ class TextureInfoTest : public testing::Test { static const GLuint kService1Id = 11; TextureInfoTest() - : manager_(kMaxTextureSize, kMaxCubeMapTextureSize) { + : manager_(false, kMaxTextureSize, kMaxCubeMapTextureSize) { } ~TextureInfoTest() { manager_.Destroy(false); @@ -186,9 +186,9 @@ TEST_F(TextureInfoTest, Basic) { EXPECT_EQ(0u, info_->target()); EXPECT_FALSE(info_->texture_complete()); EXPECT_FALSE(info_->cube_complete()); - EXPECT_FALSE(info_->CanGenerateMipmaps()); + EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_)); EXPECT_FALSE(info_->npot()); - EXPECT_FALSE(info_->CanRender()); + EXPECT_FALSE(info_->CanRender(&manager_)); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); } @@ -200,37 +200,37 @@ TEST_F(TextureInfoTest, POT2D) { 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_FALSE(info_->CanRender()); + EXPECT_FALSE(info_->CanRender(&manager_)); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); // Set filters to something that will work with a single mip. manager_.SetParameter(info_, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - EXPECT_TRUE(info_->CanRender()); + EXPECT_TRUE(info_->CanRender(&manager_)); EXPECT_FALSE(manager_.HaveUnrenderableTextures()); // Set them back. manager_.SetParameter(info_, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); - EXPECT_TRUE(info_->CanGenerateMipmaps()); + EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_)); // Make mips. EXPECT_TRUE(manager_.MarkMipmapsGenerated(info_)); EXPECT_TRUE(info_->texture_complete()); - EXPECT_TRUE(info_->CanRender()); + EXPECT_TRUE(info_->CanRender(&manager_)); EXPECT_FALSE(manager_.HaveUnrenderableTextures()); // Change a mip. manager_.SetLevelInfo(info_, 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()); - EXPECT_FALSE(info_->CanRender()); + EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_)); + EXPECT_FALSE(info_->CanRender(&manager_)); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); // Set a level past the number of mips that would get generated. manager_.SetLevelInfo(info_, GL_TEXTURE_2D, 3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); - EXPECT_TRUE(info_->CanGenerateMipmaps()); + EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_)); // Make mips. EXPECT_TRUE(manager_.MarkMipmapsGenerated(info_)); - EXPECT_FALSE(info_->CanRender()); + EXPECT_FALSE(info_->CanRender(&manager_)); EXPECT_FALSE(info_->texture_complete()); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); } @@ -243,27 +243,50 @@ TEST_F(TextureInfoTest, NPOT2D) { 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()); - EXPECT_FALSE(info_->CanRender()); + EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_)); + EXPECT_FALSE(info_->CanRender(&manager_)); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); manager_.SetParameter(info_, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - EXPECT_FALSE(info_->CanRender()); + EXPECT_FALSE(info_->CanRender(&manager_)); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); manager_.SetParameter(info_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - EXPECT_FALSE(info_->CanRender()); + EXPECT_FALSE(info_->CanRender(&manager_)); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); manager_.SetParameter(info_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - EXPECT_TRUE(info_->CanRender()); + EXPECT_TRUE(info_->CanRender(&manager_)); EXPECT_FALSE(manager_.HaveUnrenderableTextures()); // Change it to POT. manager_.SetLevelInfo(info_, 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()); + EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_)); EXPECT_FALSE(manager_.HaveUnrenderableTextures()); } +TEST_F(TextureInfoTest, NPOT2DNPOTOK) { + TextureManager manager(true, kMaxTextureSize, kMaxCubeMapTextureSize); + manager.CreateTextureInfo(kClient1Id, kService1Id); + TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); + ASSERT_TRUE(info_ != NULL); + + manager.SetInfoTarget(info, GL_TEXTURE_2D); + EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target()); + // Check Setting level 0 to NPOT + manager.SetLevelInfo(info, + 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_TRUE(info->CanGenerateMipmaps(&manager)); + EXPECT_FALSE(info->CanRender(&manager)); + EXPECT_TRUE(manager.HaveUnrenderableTextures()); + EXPECT_TRUE(manager.MarkMipmapsGenerated(info)); + EXPECT_TRUE(info->texture_complete()); + EXPECT_TRUE(info->CanRender(&manager)); + EXPECT_FALSE(manager.HaveUnrenderableTextures()); + manager.Destroy(false); +} + TEST_F(TextureInfoTest, POTCubeMap) { manager_.SetInfoTarget(info_, GL_TEXTURE_CUBE_MAP); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP), info_->target()); @@ -274,8 +297,8 @@ TEST_F(TextureInfoTest, POTCubeMap) { EXPECT_FALSE(info_->npot()); EXPECT_FALSE(info_->texture_complete()); EXPECT_FALSE(info_->cube_complete()); - EXPECT_FALSE(info_->CanGenerateMipmaps()); - EXPECT_FALSE(info_->CanRender()); + EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_)); + EXPECT_FALSE(info_->CanRender(&manager_)); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); manager_.SetLevelInfo(info_, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, @@ -283,8 +306,8 @@ TEST_F(TextureInfoTest, POTCubeMap) { EXPECT_FALSE(info_->npot()); EXPECT_FALSE(info_->texture_complete()); EXPECT_FALSE(info_->cube_complete()); - EXPECT_FALSE(info_->CanGenerateMipmaps()); - EXPECT_FALSE(info_->CanRender()); + EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_)); + EXPECT_FALSE(info_->CanRender(&manager_)); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); manager_.SetLevelInfo(info_, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, @@ -292,8 +315,8 @@ TEST_F(TextureInfoTest, POTCubeMap) { EXPECT_FALSE(info_->npot()); EXPECT_FALSE(info_->texture_complete()); EXPECT_FALSE(info_->cube_complete()); - EXPECT_FALSE(info_->CanGenerateMipmaps()); - EXPECT_FALSE(info_->CanRender()); + EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_)); + EXPECT_FALSE(info_->CanRender(&manager_)); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); manager_.SetLevelInfo(info_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, @@ -301,8 +324,8 @@ TEST_F(TextureInfoTest, POTCubeMap) { EXPECT_FALSE(info_->npot()); EXPECT_FALSE(info_->texture_complete()); EXPECT_FALSE(info_->cube_complete()); - EXPECT_FALSE(info_->CanRender()); - EXPECT_FALSE(info_->CanGenerateMipmaps()); + EXPECT_FALSE(info_->CanRender(&manager_)); + EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_)); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); manager_.SetLevelInfo(info_, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, @@ -310,8 +333,8 @@ TEST_F(TextureInfoTest, POTCubeMap) { EXPECT_FALSE(info_->npot()); EXPECT_FALSE(info_->texture_complete()); EXPECT_FALSE(info_->cube_complete()); - EXPECT_FALSE(info_->CanGenerateMipmaps()); - EXPECT_FALSE(info_->CanRender()); + EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_)); + EXPECT_FALSE(info_->CanRender(&manager_)); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); manager_.SetLevelInfo(info_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, @@ -319,15 +342,15 @@ TEST_F(TextureInfoTest, POTCubeMap) { EXPECT_FALSE(info_->npot()); EXPECT_FALSE(info_->texture_complete()); EXPECT_TRUE(info_->cube_complete()); - EXPECT_TRUE(info_->CanGenerateMipmaps()); - EXPECT_FALSE(info_->CanRender()); + EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_)); + EXPECT_FALSE(info_->CanRender(&manager_)); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); // Make mips. EXPECT_TRUE(manager_.MarkMipmapsGenerated(info_)); EXPECT_TRUE(info_->texture_complete()); EXPECT_TRUE(info_->cube_complete()); - EXPECT_TRUE(info_->CanRender()); + EXPECT_TRUE(info_->CanRender(&manager_)); EXPECT_FALSE(manager_.HaveUnrenderableTextures()); // Change a mip. @@ -337,12 +360,12 @@ TEST_F(TextureInfoTest, POTCubeMap) { EXPECT_FALSE(info_->npot()); EXPECT_FALSE(info_->texture_complete()); EXPECT_TRUE(info_->cube_complete()); - EXPECT_TRUE(info_->CanGenerateMipmaps()); + EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_)); // Set a level past the number of mips that would get generated. manager_.SetLevelInfo(info_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); - EXPECT_TRUE(info_->CanGenerateMipmaps()); + EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_)); // Make mips. EXPECT_TRUE(manager_.MarkMipmapsGenerated(info_)); EXPECT_FALSE(info_->texture_complete()); |