diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-24 18:55:49 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-24 18:55:49 +0000 |
commit | 00f893d36bc4b9bdf8d0ca824478707b8c52c550 (patch) | |
tree | 43bd4e1f3add11d9da2a1b7b94f3b88b6d33f8d4 /gpu/command_buffer | |
parent | 3b51bda549c3cb24e896703a6ce69807cf1a2ba2 (diff) | |
download | chromium_src-00f893d36bc4b9bdf8d0ca824478707b8c52c550.zip chromium_src-00f893d36bc4b9bdf8d0ca824478707b8c52c550.tar.gz chromium_src-00f893d36bc4b9bdf8d0ca824478707b8c52c550.tar.bz2 |
Fixes for the default texture.
Since we are simulating non-shared resources on top
of shared resources we can't actually let contexts
use texture 0 because they are all sharing it.
Also, moved the black textures to the texture manager.
TEST=unit tests and ran conformance tests
BUG=none
Review URL: http://codereview.chromium.org/3150026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57214 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer')
-rw-r--r-- | gpu/command_buffer/service/context_group.cc | 4 | ||||
-rw-r--r-- | gpu/command_buffer/service/context_group_unittest.cc | 63 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 48 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc | 4 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc | 85 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h | 7 | ||||
-rw-r--r-- | gpu/command_buffer/service/test_helper.cc | 129 | ||||
-rw-r--r-- | gpu/command_buffer/service/test_helper.h | 40 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.cc | 47 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.h | 14 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager_unittest.cc | 18 |
11 files changed, 286 insertions, 173 deletions
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index 5cedbbd..64150ca 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc @@ -206,6 +206,10 @@ bool ContextGroup::Initialize() { max_vertex_uniform_vectors_ /= 4; } + if (!texture_manager_->Initialize()) { + return false; + } + initialized_ = true; return true; } diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc index c8717c4..be6888e 100644 --- a/gpu/command_buffer/service/context_group_unittest.cc +++ b/gpu/command_buffer/service/context_group_unittest.cc @@ -5,6 +5,7 @@ #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/test_helper.h" #include "gpu/command_buffer/service/texture_manager.h" #include "gpu/GLES2/gles2_command_buffer.h" #include "testing/gtest/include/gtest/gtest.h" @@ -31,19 +32,11 @@ class ContextGroupTest : public testing::Test { ContextGroupTest() { } - void SetupInitExpectations(const char* extensions); + void SetupInitExpectations(const char* extensions) { + TestHelper::SetupContextGroupInitExpectations(gl_.get(), 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()); @@ -59,54 +52,6 @@ class ContextGroupTest : public testing::Test { 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(); - 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(); -} - TEST_F(ContextGroupTest, Basic) { // Test it starts off uninitialized. EXPECT_EQ(0u, group_.max_vertex_attribs()); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 639ba86..24558d1 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -273,7 +273,7 @@ class FrameBuffer { }; #if defined(GLES2_GPU_SERVICE_TRANSLATE_SHADER) -void FinalizeShaderTranslator(void*) { +void FinalizeShaderTranslator(void* /* dummy */) { ShFinalize(); } @@ -1226,12 +1226,6 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // Which textures are bound to texture units through glActiveTexture. scoped_array<TextureUnit> texture_units_; - // Black (0,0,0,1) textures for when non-renderable textures are used. - // NOTE: There is no corresponding TextureInfo for these textures. - // TextureInfos are only for textures the client side can access. - GLuint black_2d_texture_id_; - GLuint black_cube_texture_id_; - // state saved for clearing so we can clear render buffers and then // restore to these values. GLclampf clear_red_; @@ -1525,8 +1519,6 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) attrib_0_buffer_id_(0), attrib_0_size_(0), active_texture_unit_(0), - black_2d_texture_id_(0), - black_cube_texture_id_(0), clear_red_(0), clear_green_(0), clear_blue_(0), @@ -1616,28 +1608,17 @@ bool GLES2DecoderImpl::Initialize(gfx::GLContext* context, texture_units_.reset( new TextureUnit[group_->max_texture_units()]); for (uint32 tt = 0; tt < group_->max_texture_units(); ++tt) { - texture_units_[tt].bound_texture_2d = - texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D); - texture_units_[tt].bound_texture_cube_map = + glActiveTexture(GL_TEXTURE0 + tt); + // Do cube map first because we want the last bind to be 2D. + TextureManager::TextureInfo* info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP); + texture_units_[tt].bound_texture_cube_map = info; + glBindTexture(GL_TEXTURE_CUBE_MAP, info->service_id()); + info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D); + texture_units_[tt].bound_texture_2d = info; + glBindTexture(GL_TEXTURE_2D, info->service_id()); } - - GLuint ids[2]; - glGenTextures(2, ids); - // Make black textures for replacing non-renderable textures. - black_2d_texture_id_ = ids[0]; - black_cube_texture_id_ = ids[1]; - static uint8 black[] = {0, 0, 0, 255}; - glBindTexture(GL_TEXTURE_2D, black_2d_texture_id_); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, - GL_UNSIGNED_BYTE, black); - glBindTexture(GL_TEXTURE_2D, 0); - glBindTexture(GL_TEXTURE_CUBE_MAP, black_cube_texture_id_); - for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) { - glTexImage2D(GLES2Util::IndexToGLFaceTarget(ii), 0, GL_RGBA, 1, 1, 0, - GL_RGBA, GL_UNSIGNED_BYTE, black); - } - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + glActiveTexture(GL_TEXTURE0); CHECK_GL_ERROR(); if (context_->IsOffscreen()) { @@ -2115,12 +2096,6 @@ void GLES2DecoderImpl::Destroy() { if (context_.get()) { MakeCurrent(); - if (black_2d_texture_id_) { - glDeleteTextures(1, &black_2d_texture_id_); - } - if (black_cube_texture_id_) { - glDeleteTextures(1, &black_cube_texture_id_); - } if (attrib_0_buffer_id_) { glDeleteBuffersARB(1, &attrib_0_buffer_id_); } @@ -3464,8 +3439,7 @@ bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() { glBindTexture( uniform_info->type == GL_SAMPLER_2D ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP, - uniform_info->type == GL_SAMPLER_2D ? black_2d_texture_id_ : - black_cube_texture_id_); + texture_manager()->black_texture_id(uniform_info->type)); } } // else: should this be an error? diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 200f079..c282507 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -11,6 +11,7 @@ #include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/program_manager.h" +#include "gpu/command_buffer/service/test_helper.h" #include "testing/gtest/include/gtest/gtest.h" using ::gfx::MockGLInterface; @@ -96,7 +97,8 @@ TEST_F(GLES2DecoderWithShaderTest, DrawArraysBadTextureUsesBlack) { EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceBlackTexture2dId)) + EXPECT_CALL(*gl_, BindTexture( + GL_TEXTURE_2D, TestHelper::kServiceBlackTexture2dId)) .Times(1) .RetiresOnSaturation(); EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) 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 51e29dd..440440b 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -14,6 +14,7 @@ #include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/program_manager.h" +#include "gpu/command_buffer/service/test_helper.h" #include "testing/gtest/include/gtest/gtest.h" using ::gfx::MockGLInterface; @@ -41,36 +42,8 @@ void GLES2DecoderTestBase::InitDecoder(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(); - 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(); + TestHelper::SetupContextGroupInitExpectations(gl_.get(), ""); + EXPECT_CALL(*gl_, EnableVertexAttribArray(0)) .Times(1) .RetiresOnSaturation(); @@ -91,45 +64,23 @@ void GLES2DecoderTestBase::InitDecoder(const char* extensions) { .Times(1) .RetiresOnSaturation(); - static GLuint black_ids[] = { - kServiceBlackTexture2dId, - kServiceBlackTextureCubemapId, - }; - EXPECT_CALL(*gl_, GenTextures(arraysize(black_ids), _)) - .WillOnce(SetArrayArgument<1>(black_ids, - black_ids + arraysize(black_ids))) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceBlackTexture2dId)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, - GL_UNSIGNED_BYTE, _)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, - kServiceBlackTextureCubemapId)) - .Times(1) - .RetiresOnSaturation(); - static GLenum faces[] = { - GL_TEXTURE_CUBE_MAP_POSITIVE_X, - GL_TEXTURE_CUBE_MAP_NEGATIVE_X, - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, - }; - for (size_t ii = 0; ii < arraysize(faces); ++ii) { - EXPECT_CALL(*gl_, TexImage2D(faces[ii], 0, GL_RGBA, 1, 1, 0, GL_RGBA, - GL_UNSIGNED_BYTE, _)) + for (GLint tt = 0; tt < TestHelper::kNumTextureUnits; ++tt) { + EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0 + tt)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, BindTexture( + GL_TEXTURE_CUBE_MAP, TestHelper::kServiceDefaultTextureCubemapId)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, BindTexture( + GL_TEXTURE_2D, TestHelper::kServiceDefaultTexture2dId)) .Times(1) .RetiresOnSaturation(); } - EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, 0)) + EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)) .Times(1) .RetiresOnSaturation(); + EXPECT_CALL(*gl_, Enable(GL_VERTEX_PROGRAM_POINT_SIZE)) .Times(1) .RetiresOnSaturation(); @@ -186,9 +137,6 @@ void GLES2DecoderTestBase::InitDecoder(const char* extensions) { void GLES2DecoderTestBase::TearDown() { // All Tests should have read all their GLErrors before getting here. EXPECT_EQ(GL_NO_ERROR, GetGLError()); - EXPECT_CALL(*gl_, DeleteTextures(1, _)) - .Times(2) - .RetiresOnSaturation(); EXPECT_CALL(*gl_, DeleteBuffersARB(1, _)) .Times(1) .RetiresOnSaturation(); @@ -436,9 +384,6 @@ const GLint GLES2DecoderTestBase::kMaxFragmentUniformVectors; const GLint GLES2DecoderTestBase::kMaxVaryingVectors; const GLint GLES2DecoderTestBase::kMaxVertexUniformVectors; -const GLuint GLES2DecoderTestBase::kServiceBlackTexture2dId; -const GLuint GLES2DecoderTestBase::kServiceBlackTextureCubemapId; - const GLuint GLES2DecoderTestBase::kServiceAttrib0BufferId; const GLuint GLES2DecoderTestBase::kServiceBufferId; 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 d30e831..dfd78dc 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -48,9 +48,6 @@ class GLES2DecoderTestBase : public testing::Test { static const GLint kMaxVaryingVectors = 8; static const GLint kMaxVertexUniformVectors = 128; - static const GLuint kServiceBlackTexture2dId = 701; - static const GLuint kServiceBlackTextureCubemapId = 702; - static const GLuint kServiceAttrib0BufferId = 801; static const GLuint kServiceBufferId = 301; @@ -168,6 +165,10 @@ class GLES2DecoderTestBase : public testing::Test { void InitDecoder(const char* extensions); + const ContextGroup& group() const { + return group_; + } + struct AttribInfo { const char* name; GLint size; diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc new file mode 100644 index 0000000..9002e7f --- /dev/null +++ b/gpu/command_buffer/service/test_helper.cc @@ -0,0 +1,129 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/command_buffer/service/test_helper.h" +#include "app/gfx/gl/gl_mock.h" +#include "gpu/command_buffer/common/types.h" +#include "gpu/GLES2/gles2_command_buffer.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; +using ::testing::DoAll; +using ::testing::InSequence; +using ::testing::MatcherCast; +using ::testing::Pointee; +using ::testing::Return; +using ::testing::SetArrayArgument; +using ::testing::SetArgumentPointee; +using ::testing::StrEq; +using ::testing::StrictMock; + +namespace gpu { +namespace gles2 { + +// GCC requires these declarations, but MSVC requires they not be present +#ifndef COMPILER_MSVC +const GLuint TestHelper::kServiceBlackTexture2dId; +const GLuint TestHelper::kServiceBlackTextureCubemapId; +const GLuint TestHelper::kServiceDefaultTexture2dId; +const GLuint TestHelper::kServiceDefaultTextureCubemapId; + +const GLint TestHelper::kMaxTextureSize; +const GLint TestHelper::kMaxCubeMapTextureSize; +const GLint TestHelper::kNumVertexAttribs; +const GLint TestHelper::kNumTextureUnits; +const GLint TestHelper::kMaxTextureImageUnits; +const GLint TestHelper::kMaxVertexTextureImageUnits; +const GLint TestHelper::kMaxFragmentUniformVectors; +const GLint TestHelper::kMaxVaryingVectors; +const GLint TestHelper::kMaxVertexUniformVectors; +#endif + +void TestHelper::SetupTextureManagerInitExpectations( + ::gfx::MockGLInterface* gl) { + static GLuint texture_ids[] = { + kServiceBlackTexture2dId, + kServiceDefaultTexture2dId, + kServiceBlackTextureCubemapId, + kServiceDefaultTextureCubemapId, + }; + EXPECT_CALL(*gl, GenTextures(arraysize(texture_ids), _)) + .WillOnce(SetArrayArgument<1>(texture_ids, + texture_ids + arraysize(texture_ids))) + .RetiresOnSaturation(); + for (int ii = 0; ii < 2; ++ii) { + EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, texture_ids[ii])) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, + GL_UNSIGNED_BYTE, _)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_CUBE_MAP, texture_ids[2 + ii])) + .Times(1) + .RetiresOnSaturation(); + static GLenum faces[] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + }; + for (size_t ii = 0; ii < arraysize(faces); ++ii) { + EXPECT_CALL(*gl, TexImage2D(faces[ii], 0, GL_RGBA, 1, 1, 0, GL_RGBA, + GL_UNSIGNED_BYTE, _)) + .Times(1) + .RetiresOnSaturation(); + } + } + EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, 0)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_CUBE_MAP, 0)) + .Times(1) + .RetiresOnSaturation(); +} + +void TestHelper::SetupContextGroupInitExpectations( + ::gfx::MockGLInterface* gl, 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(); + 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(); + + SetupTextureManagerInitExpectations(gl); +} + +} // namespace gles2 +} // namespace gpu + diff --git a/gpu/command_buffer/service/test_helper.h b/gpu/command_buffer/service/test_helper.h new file mode 100644 index 0000000..2858b50 --- /dev/null +++ b/gpu/command_buffer/service/test_helper.h @@ -0,0 +1,40 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_TEST_HELPER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_TEST_HELPER_H_ + +#include "app/gfx/gl/gl_mock.h" +#include "gpu/GLES2/gles2_command_buffer.h" + +namespace gpu { +namespace gles2 { + +class TestHelper { + public: + static const GLuint kServiceBlackTexture2dId = 701; + static const GLuint kServiceBlackTextureCubemapId = 702; + static const GLuint kServiceDefaultTexture2dId = 703; + static const GLuint kServiceDefaultTextureCubemapId = 704; + + 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; + + static void SetupContextGroupInitExpectations( + ::gfx::MockGLInterface* gl, const char* extensions); + static void SetupTextureManagerInitExpectations(::gfx::MockGLInterface* gl); +}; + +} // namespace gles2 +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_TEST_HELPER_H_ + diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index 2556197..607938e 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc @@ -75,6 +75,15 @@ void TextureManager::Destroy(bool have_context) { } texture_infos_.erase(texture_infos_.begin()); } + if (have_context) { + GLuint ids[] = { + black_2d_texture_id_, + black_cube_texture_id_, + default_texture_2d_->service_id(), + default_texture_cube_map_->service_id(), + }; + glDeleteTextures(arraysize(ids), ids); + } } bool TextureManager::TextureInfo::CanRender( @@ -352,18 +361,50 @@ TextureManager::TextureManager( max_cube_map_levels_(ComputeMipMapCount(max_cube_map_texture_size, max_cube_map_texture_size, max_cube_map_texture_size)), - num_unrenderable_textures_(0) { - default_texture_2d_ = TextureInfo::Ref(new TextureInfo(0)); + num_unrenderable_textures_(0), + black_2d_texture_id_(0), + black_cube_texture_id_(0) { +} + +bool TextureManager::Initialize() { + // TODO(gman): The default textures have to be real textures, not the 0 + // texture because we simulate non shared resources on top of shared + // resources and all contexts that share resource share the same default + // texture. + + // Make default textures and texture for replacing non-renderable textures. + GLuint ids[4]; + glGenTextures(arraysize(ids), ids); + static uint8 black[] = {0, 0, 0, 255}; + for (int ii = 0; ii < 2; ++ii) { + glBindTexture(GL_TEXTURE_2D, ids[ii]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, + GL_UNSIGNED_BYTE, black); + glBindTexture(GL_TEXTURE_CUBE_MAP, ids[2 + ii]); + for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) { + glTexImage2D(GLES2Util::IndexToGLFaceTarget(ii), 0, GL_RGBA, 1, 1, 0, + GL_RGBA, GL_UNSIGNED_BYTE, black); + } + } + glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + + default_texture_2d_ = TextureInfo::Ref(new TextureInfo(ids[1])); SetInfoTarget(default_texture_2d_, GL_TEXTURE_2D); default_texture_2d_->SetLevelInfo( this, GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); - default_texture_cube_map_ = TextureInfo::Ref(new TextureInfo(0)); + default_texture_cube_map_ = TextureInfo::Ref(new TextureInfo(ids[3])); SetInfoTarget(default_texture_cube_map_, GL_TEXTURE_CUBE_MAP); for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) { default_texture_cube_map_->SetLevelInfo( this, GLES2Util::IndexToGLFaceTarget(ii), 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); } + + black_2d_texture_id_ = ids[0]; + black_cube_texture_id_ = ids[2]; + + return true; } bool TextureManager::ValidForTarget( diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h index 070a801..2ec46c1 100644 --- a/gpu/command_buffer/service/texture_manager.h +++ b/gpu/command_buffer/service/texture_manager.h @@ -217,6 +217,9 @@ class TextureManager { GLsizei max_cube_map_texture_size); ~TextureManager(); + // Init the texture manager. + bool Initialize(); + // Must call before destruction. void Destroy(bool have_context); @@ -302,6 +305,11 @@ class TextureManager { return num_unrenderable_textures_ > 0; } + GLuint black_texture_id(GLenum target) const { + return target == GL_SAMPLER_2D ? black_2d_texture_id_ : + black_cube_texture_id_; + } + private: // Info for each texture in the system. // TODO(gman): Choose a faster container. @@ -318,6 +326,12 @@ class TextureManager { int num_unrenderable_textures_; + // Black (0,0,0,1) textures for when non-renderable textures are used. + // NOTE: There is no corresponding TextureInfo for these textures. + // TextureInfos are only for textures the client side can access. + GLuint black_2d_texture_id_; + GLuint black_cube_texture_id_; + // The default textures for each target (texture name = 0) TextureInfo::Ref default_texture_2d_; TextureInfo::Ref default_texture_cube_map_; diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc index 5f55d32..b313b32 100644 --- a/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/gpu/command_buffer/service/texture_manager_unittest.cc @@ -7,8 +7,10 @@ #include "app/gfx/gl/gl_mock.h" #include "gpu/GLES2/gles2_command_buffer.h" #include "testing/gtest/include/gtest/gtest.h" +#include "gpu/command_buffer/service/test_helper.h" using ::testing::Pointee; +using ::testing::_; namespace gpu { namespace gles2 { @@ -20,6 +22,12 @@ class TextureManagerTest : public testing::Test { static const GLint kMax2dLevels = 5; static const GLint kMaxCubeMapLevels = 4; + static const GLuint kServiceBlackTexture2dId = 701; + static const GLuint kServiceBlackTextureCubemapId = 702; + static const GLuint kServiceDefaultTexture2dId = 703; + static const GLuint kServiceDefaultTextureCubemapId = 704; + + TextureManagerTest() : manager_(false, false, false, kMaxTextureSize, kMaxCubeMapTextureSize) { } @@ -32,6 +40,9 @@ class TextureManagerTest : public testing::Test { virtual void SetUp() { gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); ::gfx::GLInterface::SetGLInterface(gl_.get()); + + TestHelper::SetupTextureManagerInitExpectations(gl_.get()); + manager_.Initialize(); } virtual void TearDown() { @@ -50,6 +61,10 @@ const GLint TextureManagerTest::kMaxTextureSize; const GLint TextureManagerTest::kMaxCubeMapTextureSize; const GLint TextureManagerTest::kMax2dLevels; const GLint TextureManagerTest::kMaxCubeMapLevels; +const GLuint TextureManagerTest::kServiceBlackTexture2dId; +const GLuint TextureManagerTest::kServiceBlackTextureCubemapId; +const GLuint TextureManagerTest::kServiceDefaultTexture2dId; +const GLuint TextureManagerTest::kServiceDefaultTextureCubemapId; #endif TEST_F(TextureManagerTest, Basic) { @@ -87,6 +102,9 @@ TEST_F(TextureManagerTest, Destroy) { EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService1Id))) .Times(1) .RetiresOnSaturation(); + EXPECT_CALL(*gl_, DeleteTextures(4, _)) + .Times(1) + .RetiresOnSaturation(); manager_.Destroy(true); // Check that resources got freed. info1 = manager_.GetTextureInfo(kClient1Id); |